home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Programmer Disk
/
The Programmer Disk (Microforum).iso
/
xpro
/
vc
/
pro13
/
cport.doc
< prev
next >
Wrap
Text File
|
1993-11-06
|
191KB
|
5,568 lines
Cport
Serial Communications Library for C/C++
Version 2.0
Copyright (c) 1993 Bri Productions - all rights reserved
Cport is a registered trademark of Bri Productions. All other product and
brand names are trademarks or registered trademarks of their respective
holders.
i
Contents
========
Introduction
------------
General Description ............................. 1-1
Disclaimer ...................................... 1-2
Evaluation Copy ................................. 1-2
Purchase Version ................................ 1-2
Contacting Bri Productions ..................... 1-2
Terminology ..................................... 1-3
Using Cport
-----------
Basics .......................................... 2-1
Buffered Input .................................. 2-3
Buffered Output ................................. 2-5
Handshaking ..................................... 2-7
Direct Transmit Mode ............................ 2-10
Theory of Operation
-------------------
The UART ........................................ 3-1
The Transmitter and Receiver .................... 3-1
The Transmit and Receive Queues ................. 3-2
Input and Output Functions ...................... 3-2
Control and Status Functions .................... 3-2
Direct Transmit mode ............................ 3-2
C Reference
-----------
Typedefs and Structures ......................... 4-1
COM .......................................... 4-2
CPARAM ....................................... 4-2
byte ......................................... 4-3
Global Variables ................................ 4-4
comopen_errno ................................ 4-4
Control Functions ............................... 4-5
ComOpen ...................................... 4-6
ComOpenS ..................................... 4-8
ComClose ..................................... 4-8
ComCloseAll .................................. 4-9
ComHandshake ................................. 4-9
ComParam ..................................... 4-10
ComBaud ...................................... 4-11
ComMode ...................................... 4-12
ComRxQ ....................................... 4-13
ComTxQ ....................................... 4-14
ComTx ........................................ 4-15
ComNS550 ..................................... 4-15
ComTurbo ..................................... 4-16
ii
Input Functions ................................. 4-18
ComGetc ...................................... 4-19
ComGets ...................................... 4-19
ComIn ........................................ 4-20
ComFlushRx ................................... 4-21
ComLenRx ..................................... 4-22
ComPeek ...................................... 4-22
ComRxScan .................................... 4-23
Output Functions ................................ 4-25
ComPutc ...................................... 4-26
ComPuts ...................................... 4-26
ComOut ....................................... 4-27
ComFlushTx ................................... 4-28
ComLenTx ..................................... 4-29
ComTxWait .................................... 4-29
Status Functions ................................ 4-31
ComError ..................................... 4-32
ComStatus .................................... 4-33
ComRts ....................................... 4-33
ComDtr ....................................... 4-34
ComOut1 ...................................... 4-35
ComUart ...................................... 4-35
Data Integrity .................................. 4-37
ComChecksum .................................. 4-38
ComCrc16 ..................................... 4-38
ComCrc32 ..................................... 4-39
Misc Functions .................................. 4-41
ComSetBreak .................................. 4-42
ComClrBreak .................................. 4-42
ComPutScrtch ................................. 4-43
ComGetScrtch ................................. 4-43
C++ Reference
-------------
Control Functions ............................... 5-1
Cport::Cport ................................. 5-2
Cport::operator int .......................... 5-4
Cport::Handshake ............................. 5-5
Cport::Param ................................. 5-6
Cport::Baud .................................. 5-6
Cport::Mode .................................. 5-7
Cport::RxQ ................................... 5-8
Cport::TxQ ................................... 5-9
Cport::Tx .................................... 5-10
Cport::NS550 ................................. 5-10
Cport::Turbo ................................. 5-11
iii
Input Functions ................................. 5-13
Cport::Get ................................... 5-14
Cport::In .................................... 5-15
Cport::FlushRx ............................... 5-16
Cport::LenRx ................................. 5-17
Cport::Peek .................................. 5-17
Cport::RxScan ................................ 5-18
Output Functions ................................ 5-19
Cport::Put ................................... 5-20
Cport::Out ................................... 5-21
Cport::FlushTx ............................... 5-22
Cport::LenTx ................................. 5-22
Cport::TxWait ................................ 5-23
Status Functions ................................ 5-24
Cport::Error ................................. 5-25
Cport::Status ................................ 5-25
Cport::Rts ................................... 5-26
Cport::Dtr ................................... 5-27
Cport::Out1 .................................. 5-28
Cport::Uart .................................. 5-28
Data Integrity .................................. 5-29
Cport::Checksum .............................. 5-30
Cport::Crc16 ................................. 5-30
Cport::Crc32 ................................. 5-31
Misc Functions .................................. 5-33
Cport::SetBreak .............................. 5-34
Cport::ClrBreak .............................. 5-34
Cport::Scratch ............................... 5-35
File Transfer
-------------
Xmodem .......................................... 6-1
XmodemTx ........................................ 6-2
XmodemRx ........................................ 6-3
Xcallback ....................................... 6-4
Callback Function ............................... 6-5
Xmodem Tables of Values ......................... 6-7
Appendix
--------
Appendix A - Tables of Values ................... A-1
Appendix B - Compiling and Linking .............. B-1
Appendix C - Order form ......................... C-1
1-1
Introduction
============
General Description
-------------------
Cport is a general purpose C/C++ serial communications library for
80x86 Intel processor-based systems and the National Semiconductor
family of UARTs. This includes IBM and compatible computers and
potentially 80x86 processor-based embedded applications. The latter
is usually possible with few no modifications.
Cport features:
■ Support for COM 1 to COM 4 and custom configurations
■ Simultaneous serial communications.
■ Baud rates from 50 to 115200 baud.
■ Built-in hardware and software handshaking.
■ Both transmitter and receiver are interrupt-driven.
■ Adjustable transmit and receive queues.
■ Queues as large as 65534 bytes each.
■ Transmit and receive queues are handled internally.
■ Supports the NS16550 UART automatically.
■ Developed in assembly language for optimum speed and efficiency.
Cport provides a middle level C/C++ interface for general purpose
serial communications. The library is lean and fast, so as to
provide programs with high performance serial communications without
significantly increasing its size. Cport can be used to develop
higher level interfaces for specific types of serial devices or as
is for more generic types of serial communications applications. An
example of a higher level interface might be a set of functions
that communicate with a serial printer. This interface would have
more knowledge of the type of data, controls codes, protocol, etc.
that relate to a serial printer. An example of a more generic
application would be a terminal program since, like Cport, a
terminal program is indifferent to the actual significance of the
data.
The design philosophy of Cport is to provide as many features
as possible without hindering its most important attributes: speed
and size. Many of the details, in addition to the actual hardware
interface itself, are provided in order to facilitate serial
communications software development. This includes the internal
buffering (queues), hardware and software handshaking and different
flavors of input/output functions. These features would either need
to be implemented externally anyway, or do not add overhead unless used.
Many features, such as timeouts, can additionally be easily implemented
as needed at the middle, C/C++ level. Many techniques and features are
demonstrated in the next section (Using Cport) and in examples
throughout this document. Examples and techniques will continue
to be compiled and made available in the future.
1-2
DISCLAIMER
----------
Cport is provided AS IS. Bri Productions specifically disclaims any
and all warranties, expressed or implied, including but not limited
to any implied warranties including fitness for a particular purpose.
Use this product at your own risk.
Evaluation Copy
---------------
This is an evaluation copy of Cport. This evaluation copy is
provided to you at no charge* so that you may properly evaluate Cport
prior to purchasing it. This evaluation copy has a fully functional
small model library and contains no cripples. Redistribution of this
evaluation copy, unaltered and without charge, is encouraged.
We feel it is important that you be able to try a product prior
to paying for it. This ensures that you will be able to determine
the quality of a product and if it fits your needs. It avoids
the hassle of money back guarantees which would otherwise waste
your time and ours.
We also feel that the producers of a product are entitled to be
compensated for their hard work. This enables them to continue to
provide a high quality product. If you intend to use Cport beyond
the purpose evaluation, you are obligated to purchase a license.
* Disk distributors may charge a minimum (reasonable) fee for
distribution of this evaluation copy.
Licensing
---------
When you purchase a license for Cport, you will receive the small,
medium, compact, large and huge model libraries; Library source code;
Printed manual; and examples. You will also be entitled to
technical support and low cost upgrades. When you license Cport you
may incorporate any part of it into your own executable programs
without additional royalties as long as they bear your own valid
Copyright notice. Each lisense covers usage by a single person at a
time. An order form is provided in Appendix C.
Contacting Bri Productions
---------------------------
Bri Productions may be contacted by any of the following means:
Telephone: (510) 794-0616
CompuServe: 76635,2246
U.S. mail: Bri Productions
39120 Argonaut Way, Ste 772
Fremont, CA 94538-1378
1-3
Terminology
-----------
This section defines some of the terminology used in this and other
Cport documentation.
The 'computer' refers to the machine on which Cport is running.
'Remote device' refers to the device the computer is communicating
with. The actual device may be a modem, serial printer or other
communications device.
If a serial port is, 'open' it is currently performing or ready to
perform serial communications. All 'open' serial ports have a 'handle'
which is assigned when it is 'opened'. This 'handle' is passed to Cport
functions in order to identify the 'open' serial port the function is to
act upon. (In C++, instances of the Cport class are used instead of
handles).
Individual units of 'data' that are transmitted and received may be
referred to as 'characters' or 'bytes'. Technically, there is no
difference between 'characters' and bytes, however; 'characters'
usually refer to 7 or 8 bit ASCII values and 'bytes' typically refer to
8 bit binary data. 'Data' refers to 'characters'/'bytes' in general.
A 'signal' may refer to software (i.e. control characters) as well
as actual hardware lines. This mainly refers to XON (ctrl-Q) and
XOFF (ctrl-S), which are used in software handshaking. 'Signals' may
be either inputs or outputs. A 'signal' is said to be 'asserted' if
it is in a true/on state and 'inhibited' if it is in a false/off
state. This stems from the idea that a 'signal' can be used to allow
(assert) or preclude (inhibit) something such as the transmission of
'data'.
2-1
Using Cport
===========
Basics
------
Before a serial port can be accessed, it must be opened. The open
functions identify the serial port by it's port address and
interrupt request line. The parameter id contains the port base
address in the lower 12 bits and the irq number in the upper 4 bits
of id. The open functions also take parameters that describe the
baud rate, word length, number of stop bits, parity check, and
transmit and receive queue sizes. If a serial port is successfully
opened, a handle to the newly opened serial port is returned to the
caller. This handle is used to reference the serial port in
subsequent calls to Cport functions. (C++ uses instances of the
Cport class instead of handles). If the serial port cannot be
opened, the open function returns NULL and sets the global variable
'comopen_errno' to an error code. (C++ uses an int typecast instead
of the global variable to hold the error code).
Before a program terminates, the serial port must be closed to make
certain restorations. Failing to close a serial port will leave
these restorations undone and almost certainly cause the system to
lock up. In C++, the serial port is closed automatically when it goes
out of scope (destructor).
2-2
C Example:
#include <stdio.h>
#include "cport.h"
int main(void)
{
COM com; /* declare a serial port handle */
/* Open the serial port and get/store the serial port handle
*/
com = ComOpen(COM1, B9600, W8|S1|NONE, 1024, 512);
/* Check for a NULL handle. If the handle is NULL check
// comopen_errno for the cause
*/
if(com == NULL)
{
puts("ERROR: unable to open serial port");
return(comopen_errno);
}
/* Put a string to the newly opened serial port
*/
ComPuts(com, "Hello Cport");
... The rest of the program here
/* Close the serial port before exiting
*/
ComClose(com);
return(0);
}
C++ Example:
#include <iostream.h>
#include "cport.h"
int main(void)
{
Cport com(COM1, B9600, W8|S1|NONE, 1024, 512);
if((int)com != NO_ERR) // uses int typecast
{
cout << "ERROR: unable to open serial port" << endl;
return(com);
}
com.Put("Hello Cport");
... The rest of the program here
// The serial port is closed automatically by
// the destructor.
return(0);
}
2-3
Buffered Input
--------------
When data is received, it is placed into the receive queue and stays
there until an input function retrieves it. Input functions will
only fetch whatever data is existing in the receive queue at
the time the input function is called. If a specified length of data
is expected, the receive queue can be queried to determine if enough
data is available to call an input function. This is a common case
with serial devices that send specific length messages terminated
by a specific character (often '\n' or '\r'). In the examples, the
function fetches a message only if one is available. If the message
is not available, it returns a zero, If a message is available, the
measurement is copied to the caller's buffer and a 1 is returned.
C Example:
#define MSG_LEN 24
#define TERM_C '\n'
int GetMessage(COM com, char *buf)
{
if(ComLenRx(com) > MSG_LEN)
{
ComGets(com, buf, MSG_LEN, TERM_C);
return(1);
}
return(0);
}
C++ Example:
#define MSG_LEN 24
#define TERM_C '\n'
int GetMessage(Cport& com, char *buf)
{
if(com.LenRx() > MSG_LEN)
{
com.Get(buf, MSG_LEN, TERM_C);
return(1);
}
return(0);
}
If the messages are not of a specific length, the receive queue can
be scanned for a particular character, namely the termination
character. Scanning for a character is also possible with specific
length messages but is slower than checking the length of the
receive queue. In the following examples, the function fetches a
message only if one is available. If the message is not available it
returns a zero, If a message is available, the measurement is
copied to the caller's buffer and a 1 is returned. If the message
is longer that the specified maximum message length, a -1 is
returned.
2-4
C Example:
#define MAX_MSG_LEN 80
#define TERM_C '\n'
int GetMessage(COM com, char *buf)
{
int len;
len = ComRxScan(com, TERM_C);
if(len > MAX_MSG_LEN)
return(-1);
else if(len > 0)
ComGets(com, buf, MAX_MSG_LEN, TERM_C);
return(len != 0);
}
C++ Example:
#define MAX_MSG_LEN 80
#define TERM_C '\n'
int GetMessage(Cport& com, char *buf)
{
int len;
len = com.RxScan(TERM_C);
if(len > MAX_MSG_LEN)
return(-1);
else if(len > 0)
com.Get(buf, MAX_MSG_LEN, TERM_C);
return(len != 0);
}
The previous examples are ideal for event driven routines. They do
not wait for a message to be received if one is not ready.
This allows a program to process other tasks instead of holding up
program execution while waiting for a message. On the contrary, one
may want to wait for a message, perhaps within a certain time frame.
Revisiting the first example, we can add a timeout using the ANSI C
compatible function, clock.
2-5
C Example:
#include <time.h>
#define MSG_LEN 24
#define TERM_C '\n'
int GetMessage(COM com, char *buf, clock_t timeout)
{
timeout += clock();
while(ComLenRx(com) <= MSG_LEN)
{
if(clock() > timeout)
return(0);
}
ComGets(com, buf, MSG_LEN, TERM_C);
return(1);
}
C++ Example:
#include <time.h>
#define MSG_LEN 24
#define TERM_C '\n'
int GetMessage(Cport& com, char *buf, clock_t timeout)
{
timeout += clock();
while(com.LenRx() <= MSG_LEN)
{
if(clock() > timeout)
return(0);
}
com.Get(buf, MSG_LEN, TERM_C);
return(1);
}
Buffered Output
---------------
When an output function inserts data into the transmit queue, it
does not wait for the data to be transmitted before the function
returns. Instead the transmitter will subsequently remove the data,
one byte/character at a time, in the order in which it was inserted and
transmit them in the background. This allows the program to continue
with more important tasks instead of waiting for the data to
transmit at a relatively slow rate (compared to the processor).
At certain points in a program, one may want to ensure that all the
data thus far has been transmitted. To do this the transmit queue
can be queried to determine how many bytes/characters still reside
there. The following examples make sure all data finishes
transmitting before the program is terminated.
2-6
C Example:
int main(void)
{
COM com;
com = ComOpen(COM2,B9600,W8|S1|NONE,512,2048);
if(com == NULL)
return(comopen_errno);
ComPuts(com, "Welcome to Bri Productions");
while(ComLenTx(com) != 0);
ComClose(com);
return(0);
}
C++ Example:
int main(void)
{
Cport com(COM2, B9600, W8|S1|NONE, 512, 2048);
if((int)com != NO_ERR)
return(com);
com.Put("Welcome to Bri Productions");
while(com.LenTx() != 0);
// The serial port is closed automatically by
// the destructor.
return(0);
}
Querying the transmit queue can also be useful in determining if
there is enough room for new data. In the following, example a
message is sent only if there is enough room for the whole message.
The value returned should always be 0 (if not enough room) or the
length of the message (number of characters put by ComPuts).
C Example:
#include <string.h>
#define TXSIZE 1024
int PutMessage(COM com, const char *buffer)
{
if(TXSIZE - ComLenTx(com) < strlen(buffer))
return(0);
return(ComPuts(com, buffer));
}
2-7
C++ Example:
#include <string.h>
#define TXSIZE 1024
int PutMessage(Cport& com, const char *buffer)
{
if(TXSIZE - com.LenTx() < strlen(buffer))
return(0);
return(com.Put(buffer));
}
If the transmit queue length is not checked and an output function
is called without enough room for all the data, the number of
byte/characters that did fit is returned. This value can be used
as an offset into the data to determine the first byte/character
that there was no room for. The following examples will not return
until all the characters in the message are put to the queue.
C Example:
void PutMessage(COM com, const char *buffer)
{
const char *_buffer = buffer;
while(*_buffer != '\0')
_buffer += ComPuts(com, _buffer);
}
C++ Example:
void PutMessage(Cport& com, const char *buffer)
{
const char *_buffer = buffer;
while(*_buffer != '\0')
_buffer += com.Put(_buffer);
}
Handshaking
-----------
There are number of built-in options available for implementing
handshaking. The options can be divided into two categories. One is
hardware handshaking and the other is software handshaking. In
hardware handshaking, one or more of the hardware lines is used.
In software handshaking, XON and XOFF characters are used.
2-8
Hardware Handshaking
--------------------
In hardware handshaking, any combination of the hardware signals
RTS, DTR, DSR, CTS, and DCD can be used to achieve handshaking. RTS
and/or DTR are used by the receiver to signal the remote device to
suspend or resume transmitting. Similarly, DSR, CTS, and/or DCD can
be used by the remote device's receiver to signal the transmitter to
suspend or resume transmitting.
Software Handshaking
--------------------
In software handshaking, the control characters XON (ctrl-Q) and
XOFF (ctrl-S) are used to achieve handshaking. When receiver
software handshaking (S_RX) is enabled, XON and XOFF characters are
transmitted to signal the remote device to suspend or resume it's
transmission. Notice that even though the XON and XOFF characters
are sent by the transmitter, it is the receiver that exercises the
handshaking in order to preclude a receive queue overflow. In
transmit software handshaking (S_TX), the remote device sends XON
and XOFF characters to suspend and resume the computer's
transmission. Notice that even though the XON and XOFF characters
are received, it is the transmitter that is affected. Both receive
and transmit handshaking can be enabled simultaneously.
The Receiver
------------
When receive software (S_RX) and/or hardware handshaking (DTR and/or
RTS) are enabled, the receiver monitors the length of the receive
queue. If the length exceeds the specified threshold, the receiver
will take the appropriate action to signal the remote device to
suspend transmitting. When the length of the receive queue
subsequently falls below half of the set threshold, the appropriate
action is taken to signal the remote device to resume transmitting.
The Transmitter
---------------
When transmit software (S_TX) and/or hardware handshaking (DSR, CTS,
and/or DCD) are enabled and the computer is signaled to suspend
transmitting with the corresponding handshaking enabled, the
transmitter will stop transmitting. Subsequently, when the computer
is signaled to resume transmitting, the transmitter will pick up
where it left off.
User Handshaking
----------------
Another option for implementing handshaking is for the programmer to
implement their own handshaking scheme. To accomplish this, Cport
provides the function ComTx. ComTx allows the programmer to turn the
transmitter on and off. When the transmitter is turned off,
transmitting halts immediately. If any characters still reside in
the transmit queue, they will remain there until the transmitter is
turned back on or the transmit queue is flushed. More characters may
be put into the transmit queue while the transmitter is turned off.
2-9
Cooperation
-----------
In any handshaking scheme, it is imperative that the computer and
the remote device recognize the same handshaking scheme. For
instance, if the remote device recognizes hardware handshaking and
the computer does not, the computer will ignore any requests by the
remote device to suspend transmitting. If the remote device
recognized software handshaking and the computer did not, bogus XON
and XOFF characters might corrupt the received data.
In the first example, the transmitter will not transmit unless CTS
and DSR are asserted. The receiver will inhibit RTS if the receive
queue exceeds 768 bytes/characters and assert it when it
subsequently falls below 768 / 2. In the second example, the
transmitter will stop if an XOFF character is received and restart
when an XON character is received. If the receive queue length
exceeds 768 bytes/characters, an XOFF character will be transmitted
and when the length subsequently falls below 768 / 2, an XON
character is transmitted.
C Example 1
int main(void)
{
COM com;
com = ComOpen(COM1, B9600, W7|S1|EVEN, 1024,256);
if(com == NULL)
return(comopen_errno);
ComHandshake(com, CTS | DSR | RTS, 768);
/* rest of the program */
ComClose(com);
return(0);
}
C++ Example 1
int main(void)
{
Cport com(COM1, B9600, W7|S1|EVEN, 1024, 256, CTS|DSR|RTS, 768);
if((int)com)
return(com);
// rest of the program
return(0);
}
2-10
C Example 2
int main(void)
{
COM com;
com = ComOpen(COM1, B9600, W7|S1|EVEN, 1024, 256);
if(com == NULL)
return(comopen_errno);
ComHandshake(com, SOFT, 768); /* SOFT == S_RX | S_TX */
/* rest of the program */
ComClose(com);
return(0);
}
C++ Example 2
int main(void)
{
// SOFT == S_RX | S_TX
Cport com(COM1, B9600, W7|S1|EVEN, 1024, 256, SOFT, 768);
if((int)com)
return(com);
// rest of the program
return(0);
}
Direct Transmit Mode
--------------------
In direct transmit mode, data is sent directly to the serial port.
The output functions will only return after all the data has been
transmitted or when a handshaking signal is inhibited. Direct mode
is ideal for transmit intensive routines such as file transfers, where
the main task is transmitting data. Otherwise direct transmit mode
is not normally preferred.
There are two ways to get into direct transmit mode. The first is to
set the transmit queue size in the call to the open function (or
constructor in C++) to zero. This method sets direct transmit mode
permanently. To set direct transmit mode temporarily, turn the
transmitter off with ComTx with the TX_DIRECT option.
2-11
C Example 1
int main(void)
{
COM com;
/* transmit queue 0 = direct transmit mode
*/
com = ComOpen(COM1, B9600, W8 | S1 | NONE, 4096, 0);
if(com == NULL)
return(comopen_errno);
/* continued */
ComClose(com);
return(0);
}
C++ Example 1
int main(void)
{
// transmit queue 0 = direct transmit mode
Cport com(COM1, B9600, W8 | S1 | NONE, 4096, 0);
// continued
return(0);
}
In this examples, the transmitter is put into direct mode while a
block of data is transmitted. The transmitter is subsequently
restored to its previous state. The block of data is completely
transmitted before the function returns (assumes no transmit
handshaking is enabled).
C Example 2
#define BLOCK_SIZE 1024
int SendBlock(COM com, byte *block)
{
int tx, rv;
tx = ComTx(com, OFF | TX_DIRECT);
rv = ComOut(com, block, BLOCK_SIZE);
ComTx(com, tx);
return(rv);
}
2-12
C Example 2
#define BLOCK_SIZE 1024
int SendBlock(Cport& com, byte *block)
{
int tx, rv;
tx = com.Tx( OFF | TX_DIRECT);
rv = com.Out(block, BLOCK_SIZE);
com.Tx(tx);
return(rv);
}
Handshaking in Direct Transmit Mode
-----------------------------------
Transmit handshaking works a bit differently in direct transmit
mode. In normal transmit handshaking, output functions will always
succeed in putting the data as long as there is room in the transmit
queue, even if transmit handshaking is in an inhibited state. In
direct transmit mode, there is no transmit queue to buffer the output
data during the inhibited state of transmit handshaking. Therefore,
in direct transmit mode, an output function may not complete a
transmission of the data if transmit handshaking changes to an
inhibited state.
The return value of the output functions should always be tested when
transmit handshaking is used in direct transmit mode to ensure that all
of the data has been transmitted. The return value can subsequently be
used to transmit the remaining data when the transmit handshaking
returns to an asserted state. This is demonstrated in the following
example. In this example, it is assumed that DSR handshaking is enabled
and the transmitter is in direct mode.
C Example:
void SendData(COM com, char *buf)
{
char *_buf = buf;
while(*_buf != '\0')
{
_buf += ComPuts(com, _buf);
if(*_buf != '\0')
while(!ComStatus(com) & DSR); /* wait for DSR */
}
}
2-13
C++ Example
void SendData(Cport& com, char *buf)
{
char *_buf = buf;
while(*_buf != '\0')
{
_buf += com.Put(_buf);
if(*_buf != '\0')
while(!com.Status() & DSR); // wait for DSR
}
}
Receive handshaking will always function the same regardless of the
current mode of the transmitter.
3-1
Theory of Operation
===================
The UART
--------
The UART (Universal Asynchronous Receiver/Transmitter) is a single
integrated circuit peripheral chip, which is specially designed for
asynchronous serial communications. It is responsible for many of
the electronic details of serial communications. The UART converts
parallel data (bytes/characters) to and from serial signals at the
correct baud rate, and with the assigned word length, stop bits and
parity. It also monitors and controls the hardware status lines.
Cport interfaces intimately with the serial port's UART.
The name UART is a generic name used to describe a type of
integrated circuit. serial communications in IBM and compatible
computers is based on the National Semiconductor family of UARTs.
These chips include:
INS8250
INS8250-B
INS8250A
INS82C50A
NS16450
NS16C450
NS16550A
The latest and greatest is the NS16550A, which features transmitter
and receiver FIFO's. If a NS16550 UART is detected by Cport when a
serial port is opened, Cport will automatically take advantage of
it's advanced features. These feature greatly improve performance.
The Transmitter and Receiver
----------------------------
The transmitter and receiver interact intimately with the serial
port's UART to coordinate data exchanges between it and the transmit
and receive queues. They also coordinate and control any enabled
handshaking. The transmitter and receiver together constitute an
interrupt service routine that the program will branch to any time
the serial port's UART generates an interrupt.
When the UART is ready for another byte/character, the transmitter
will transfer another byte/character (if available) to the UART. In
addition, it sends XON/XOFF characters at the request of the receiver
when software handshaking is enabled, and monitors the status of the
input hardware lines when hardware handshaking in enables.
When the UART receives a new byte/character, the receiver fetches
it from the UART and stores it in the receive queue. It also
monitors the amount of data in the receive queue when handshaking is
enabled, in order to perform the enabled handshaking and avoid a
receive queue overflow. In software handshaking, requests to the
transmitter are made to send the XON/XOFF characters. In hardware
handshaking, the receiver manipulates the hardware line(s) directly.
3-2
The Transmit and Receive Queues
-------------------------------
The receive and transmit queues provide the interface/buffering
between the Cport input and output functions and the receiver and
transmitter respectively. This allows the transmitter/receiver to
operate independently from the input/output functions and vice
versa. The transmitter is concerned only with the head of the
transmit queue while the output functions are only concerned with
the tail of the transmit queue. Similarly, the receiver is only
concerned with the tail of the receive queue while the input
functions are only concerned with the head of the receive queue.
Input and Output Functions
--------------------------
Input functions retrieve data from the receive queue in the order in
which it is placed into the receive queue by the receiver. Since the
data is buffered, the program does not need to worry about the
incoming data until it is ready to fetch it. The output functions
insert data into the transmit queue and will be transmitted by the
transmitter in the order in which the data is inserted.
Control and Status Functions
----------------------------
Control functions manipulate both the transmitter/receiver and the
UART. The queues are independent of the control functions except
when the queues are created and destroyed when the serial port is
opened and close respectively. Status functions retrieve information
from the transmitter/receiver and the UART. They also manipulate the
UART to set status (to the remote unit).
Direct Transmit Mode
--------------------
In direct transmit mode, the transmitter and transmit queue are
removed. The output functions write directly to the UART. The output
functions will return only after all it's data is written to the
UART, or transmit handshaking is enabled and in an inhibited state.
This holds up program execution but may be desirable when there are
no other tasks to perform, since otherwise, the transmitter and
receiver share available background time. An example of when direct
transmit mode might be advantageous is a dedicated file transfer
routine where the only interest is to transmit data.
4-1
C Reference
===========
Typedefs and Structures
-----------------------
Basic
COM is a typedef used for storing a serial port handle.
CPARAM is a structure type used for storing a serial port's parameters.
byte is a typedef userd for storing a byte size value.
4-2
COM
------------------------------------------------------------------
Function Data type for storing a serial port handle.
Syntax #include "cport.h"
typedef void* COM;
Remarks COM is a type used to store a serial port handle. The open
functions (ComOpen and ComOpenS) return values of type COM and
all serial port specific functions take a parameter of type COM.
Example Open a serial port.
int main(void)
{
COM com1;
com1 = ComOpen(COM1, B9600, W8|S1|NONE, 1024, 512);
if(com1 == NULL)
{
/* error */
}
...continued
CPARAM
------------------------------------------------------------------
Function Data type for storing a serial port's parameters.
Syntax #include "cport.h"
typedef struct
{
unsigned id;
int baud;
byte mode;
unsigned rxQ;
unsigned txQ;
byte htype;
unsigned thresh;
}CPARAM;
id - Value that identifies the serial port. The upper 4 bits define
the interrupt request line while the lower 12 bits define the
port address. This technique allows for the possibility
of custom configurations. See Table A-1 in Appendix A for a list
of predefined values.
baud - Value that defines the baud rate. The actual value is the baud
rate divisor, which allows for the possibility of custom baud
rates. The baud rate divisor = f / (16 * baud rate) where f is
1.8432e+6. See Table A-2 in Appendix A for a list of predefined
baud rate divisors.
mode - Bit ORed value defining the word length, number of stop bits
and the parity. See Table A-3 in Appendix A for a list of mode
components.
4-3
* rxQ - Size, in bytes, of the receive queue.
* txQ - Size in bytes, of the transmit queue.
* Limited to 32K in small and medium memory models.
htype - Type of handshaking to be used. See Table A-5 in Appendix A
for a list of handshaking components.
thresh - Receive queue threshold.
Remarks CPARAM is a structure type that holds the parameters of a
serial port. This structure is mainly used with the alternate
open function ComOpenS and with the function ComParam.
Example Open COM2 at 9600 baud, 8 bits, 1 stop bit, no parity, a
receive queue of 1024 bytes, a transmit queue of 512 bytes and
software handshaking (XON/XOFF) with a receive queue threshold of
3072 bytes.
int main(void)
{
CPARAM param= {COM2, B9600, W8|S1|NONE, 4096, 512, SOFT, 3072};
COM com2;
com2 = ComOpenS(¶m);
if(com2 == NULL)
{
/* error */
}
...continued
byte
------------------------------------------------------------------
Function Data type used for storing byte size values.
Syntax #include "cport.h"
typedef unsigned character byte;
Remarks The byte data type is used for storing byte size values. Some
of the Cport functions take parameters of type byte and some
return values of type byte.
Example Use a byte data type for the mode parameter.
static byte mode = W8|S1|NONE;
byte Mode(COM terminal, byte newmode)
{
byte temp;
ComMode(terminal, newmode);
temp = mode;
mode = newmode;
return(temp); /* return previous mode */
}
4-4
Global Variables
----------------
comopen_errno
------------------------------------------------------------------
Function Holds the error code from the last attempt to open a serial
port.
Syntax #include "cport.h"
extern int comopen_errno;
Remarks Comopen_errno holds the error code from the last attempt to
open a serial port via a call to ComOpen or ComOpenS. If the
last opened serial port was successfully opened, comopen_errno
will be 0. If an error occurred while attempting to open the
serial port the value of comopen_errno will be non-zero. See
Table A-4 in Appendix A for a list of possible values for
comopen_errno.
Example Attempt to open COM1. If an error occurs, check comopen_errno
for the cause.
int main(void)
{
COM com1;
com1 = ComOpen(COM1, B9600, W8|S1|NONE, 1024, 512);
if(com1 == NULL)
{
switch(comopen_errno)
{
case RX_ALC:
case TX_ALC:
case GEN_ALC:
/* memory allocation error */
break;
case NO_UART:
/* no UART at that address */
break;
default:
/* all other errors */
break;
}
}
...continued
4-5
Control Functions
-----------------
Basic
ComOpen opens a serial port using discrete parameters.
ComOpenS opens a serial port using a structure of parameters.
ComClose closes a currently open serial port.
ComCloseAll closes all open serial ports.
ComHandshake determines if and what type of handshaking scheme will be
enabled and sets the receiver threshold.
Intermediate
ComParam reports on the current parameters and handshaking under which
the specified serial port is currently operating.
ComBaud changes the serial port's baud rate.
ComMode changes the serial port's word length, number of stop bits and
parity.
Advanced
ComRxQ resizes the receive queue.
ComTxQ resizes the transmit queue.
ComTx allows advanced control over the Cport transmitter.
ComNS550 sets the receive fifo threshold of an NS16550 UART.
ComTurbo temporarily disables/re-enables selected high priority
interrupts that may impede high speed transfers.
4-6
ComOpen
------------------------------------------------------------------
Function Opens a serial port for communications.
Syntax #include "cport.h"
COM ComOpen(unsigned id, int baud, byte mode,
unsigned rxQ, unsigned txQ);
Parameters
id - Value that identifies the serial port. The upper 4 bits define
the interrupt request line, while the lower 12 bits define the
port address. This technique allows for possibility of custom
configurations. See Table A-1 in Appendix A for a list of
predefined values.
baud - Value that defines the baud rate. The actual value is the baud
rate divisor, which allows for the possibility of custom baud
rates. The baud rate divisor = f / (16 * baud rate) where f is
1.8432e+6. See Table A-2 in Appendix A for a list of predefined
baud rate divisors.
mode - Bit ORed value defining the word length, number of stop bits
and the parity. See Table A-3 in Appendix A for a list of mode
components.
* rxQ - Size, in bytes, of the receive queue.
* txQ - Size, in bytes, of the transmit queue.
* Limited to 32K in small and medium memory models.
Remarks ComOpen opens the specified serial port and returns a handle
used to identify the newly opened serial port. If ComOpen fails
to open the specified serial port, it returns NULL and sets
comopen_errno to an error code. The 4 most significant bits in
id represent the interrupt vector, while the lower 12 bits
represent the port address. Constants are provided in cport.h
to facilitate the formulation of the id parameter. The COMx
values will work in most cases; however, the IRQx values can
be ORed with the PORTx or BIOSx values to produce other
combinations. The PORTx values are actual port addresses where
the serial ports are normally located. The BIOSx values are
actually macros, which fetch the port address from the BIOS data
area. Usually the BIOSx and PORTx values will be the same, but
it is not guaranteed. Quite often the values at BIOS2 and BIOS3
(com 3 and com 4) will be set to 0 regardless if com3 or com4
exist. See Table A-1 in Appendix A for a list of predefined
values for formulating the id parameter.
The parameter baud is the baud rate divisor that determines the
baud rate. Achieving baud rates above 19200 is depends on many
variables such as machine speed, cable length, handshaking
activity, degree bidirectional transfers, number of open serial
ports, the type UART(s) used and activity of other hardware
interrupts.
4-7
The parameter mode determines the word length, number of stop
bits and parity. Bits 0 and 1 determine the word length, bit 2
determines the number of stop bits, bit 3 enables parity and
bits 4 and 5 determine the type of parity check.
RxQ and txQ set the size of the receive and transmit queues
respectively. RxQ should be at least four times larger than the
largest string or block of data the programmer intends to fetch
from the queue at once. TxQ can be set as small as 1, but is
not recommended. In the small and medium memory models, where
all data is limited to 64K, the size queues are limited. In the
compact and large memory models, each queue can be as large as
64K-1 (65534 bytes).
Return value If successful, ComOpen returns a handle to the newly opened
serial port. In the event of an error, it returns NULL and
sets the global variable comopen_errno to an error code.
See Table A-4 in Appendix A for a list of possible values
for comopen_errno.
See also ComOpenS, ComClose, ComCloseAll, ComBaud, ComMode, COM,
comopen_errno
Example Open COM1 at 9600 baud with 8 bit words, 1 stop bit, no parity,
a 1024 byte receiver and a 512 byte transmitter.
int main(void)
{
COM com1;
com1 = ComOpen(COM1, B9600, W8|S1|NONE, 1024, 512);
if(com1 == NULL)
{
switch(comopen_errno)
{
case RX_ALC:
case TX_ALC:
case GEN_ALC:
/* allocation error */
break;
case NO_UART:
/* no UART */
break;
default:
/* all other errors */
break;
}
}
...continued
4-8
ComOpenS
------------------------------------------------------------------
Function Opens a serial port for communications.
Syntax #include "cport.h"
COM ComOpenS(const CPARAM *param);
Parameters
param - Pointer to a type CPARAM that contains the serial port
parameters.
Remarks ComOpenS is an alternative to ComOpen for opening a serial port.
It takes a pointer to a type CPARAM. CPARAM is a structure
that contains the serial port parameters.
Return value If successful, ComOpenS returns a handle to the newly opened
serial port. In the event of an error, it returns NULL and
sets the global variable comopen_errno to an error code.
See Table A-4 in Appendix A for a list of possible values
for comopen_errno.
See also ComOpen, ComClose, ComCloseAll, ComParam, COM, comopen_errno
Example Open COM2 at 9600 baud, 8 bits, 1 stop bit, no parity, a
receive queue of 1024 bytes, with a transmit queue of 512
bytes and software handshaking (XON/XOFF) with a receive queue
threshold of 3072 bytes.
int main(void)
{
CPARAM param = {COM2, B9600, W8|S1|NONE, 4096, 512, SOFT, 3072};
COM com2;
com2 = ComOpenS(¶m);
if(com2 == NULL)
{
/* error */
}
...continued
ComClose
------------------------------------------------------------------
Function Closes the specified serial port.
Syntax #include "cport.h"
void ComClose(COM);
Parameters
COM - Handle of the serial port to be closed.
4-9
Remarks ComClose closes the specified serial port. Failing to close all
serial ports before a program is terminated will cause the
system to lock up.
See also ComCloseAll, ComOpen, ComOpenS, COM
Example Close the serial port prior to terminating.
int main(void)
{
COM com1;
com1 = ComOpen(COM1, B9600, W8|S1|NONE, 1024, 512);
if(com1 == NULL)
/* error */
...later
ComClose(com1);
return(0);
}
ComCloseAll
------------------------------------------------------------------
Function Closes all currently opened serial ports.
Syntax #include "cport.h"
void ComCloseAll(void);
Remarks ComCloseAll closes all the currently opened serial ports.
Failing to close all serial ports before a program is
terminated will cause the system to lock up. ComCloseAll is
convenient for ensuring all serial ports are closed prior to a
program's termination.
See also ComClose, ComOpen, ComOpenS
Example Make sure all serial ports are closed prior to terminating.
void ErrorExit(void)
{
ComCloseAll();
exit(-1);
}
ComHandshake
------------------------------------------------------------------
Function Enables or disables handshaking (flow control) for the
specified serial port.
Syntax #include "cport.h"
void ComHandshake(COM, byte htype, unsigned thresh);
4-10
Parameters
COM - Handle of the serial port.
htype - Type of handshaking to be used. See Table A-5 in Appendix A
for a list of handshaking components.
thresh - Receive queue threshold.
Remarks ComHandshake enables or disables software and/or hardware
handshaking for the specified serial port. In software
handshaking, XON and XOFF characters are used to suspend and
resume communications. Hardware handshaking uses any or all of
the DTR, DSR, RTS, CTS and DCD lines to suspend and resume
communications. Thresh determines when the receiver will
assert or inhibit the corresponding handshaking signals. If
no receive handshaking is specified (RTS, DTR or S_RX), the
threshold is not used and may be set to zero.
See also ComParam, ComOpenS, ComTx
Example If COM1 is successfully opened, turn on some hardware
handshaking and set the receiver threshold to 3/4 of the
receiver's full size. The transmitter will not transmit unless
both DSR and DCD are asserted. The receiver will inhibit DTR if
the receive queue length exceeds the threshold.
int main(void)
{
COM com1;
com1 = ComOpen(COM1, B9600, W8|S1|NONE, 1024, 512);
if(com1 == NULL)
{
/* error */
}
ComHandshake(com1, DSR|DTR|DCD, 768);
...continued
ComClose(com1);
return(0);
}
ComParam
------------------------------------------------------------------
Function Retrieves the parameters of the specified serial port.
Syntax #include "cport.h"
void ComParam(COM, CPARAM *param);
Parameters
COM - Handle of the serial port from which to get the parameters.
4-11
param - Pointer to a type CPARAM where the parameters will be stored.
Remarks ComParam retrieves the parameters and handshaking status of the
specified serial port and stores them in a type CPARAM.
See also CPARAM, ComOpen, ComOpenS, ComMode, ComBaud
Example Open a serial port with the same configuration as one that is
already opened.
COM ComOpenCopy(unsigned id, COM copyme)
{
CPARAM param;
ComParam(copyme, ¶m);
param.id = id;
return(ComOpenS(¶m));
}
ComBaud
------------------------------------------------------------------
Function Changes the baud rate of the specified serial port.
Syntax #include "cport.h"
void ComBaud(COM, int baud);
Parameters
COM - Handle of the serial port.
baud - Value that defines the baud rate. The actual value is the baud
rate divisor, which allows for possibility of custom baud rates.
The baud rate divisor = f / (16 * baud rate) where f is
1.8432e+6. See Table A-2 in Appendix A for a list of predefined
baud rate divisors.
Remarks ComBaud changes the baud rate of the specified serial port. The
parameter baud is the baud rate divisor that determines the
baud rate.
See also ComOpen, ComOpenS, ComParam, ComMode
Example Set the specified serial port to a new baud rate.
4-12
#define NBAUD 4
int SetBaud(COM com, unsigned n)
{
int baud[NBAUD] = { B9600, B2400, B1200, B300 };
if(n < NBAUD)
{
ComBaud(com, baud[n]);
return(0);
}
else
return(-1);
}
ComMode
------------------------------------------------------------------
Function Changes the word length, number of stop bits and parity of the
specified serial port.
Syntax #include "cport.h"
void ComMode(COM, byte mode);
Parameters
COM - Handle of the serial port.
mode - Bit ORed value defining the word length, number of stop bits
and the parity. See Table A-3 in Appendix A for a list of mode
components.
Remarks ComMode changes the word length, number of stop bits and parity
of the specified serial port. The parameter mode determines the
word length, number of stop bits and parity of the specified
serial port. Bits 0 and 1 determine the word length, bit 2
determines the number of stop bits, bit 3 enables parity and
bits 4 and 5 determine the type of parity check.
See also ComOpen, ComOpenS, ComParam, ComBaud
Example Set the serial port to a new mode.
#define NMODE 2
int SetMode(COM com, unsigned n)
{
byte mode[NMODE] = { W8|S1|NONE, W7|S1|EVEN };
if(n < NMODE)
{
ComMode(com, mode[n]);
return(0);
}
return(-1);
}
4-13
ComRxQ
------------------------------------------------------------------
Function Resizes the specified serial port's receive queue.
Syntax #include "cport.h"
unsigned ComRxQ(COM, unsigned size);
Parameters
COM - Handle of the serial port.
size - New receive queue size.
Remarks ComRxQ resizes the specified serial port's receive queue. The
memory currently allocated for the receive queue is freed, and
new memory is allocated. If ComRxQ is unable to allocate the
specified amount memory, it will try to reallocate memory for
the previous size. ComRxQ returns the new queue size. If
memory was successfully allocated for the new size, the return
value will be size. If the previous size is reallocated, the
return value will be the previous size. If no memory could be
allocated, ComRxQ returns zero.
No data can be received while the new receive queue is being
resized. However, data in the transmit queue will continue to
be transmitted normally.
Return value ComRxQ returns the new receive queue size.
See also ComTxQ, ComOpen, ComOpenS
Example Enlarge the receive queue for a file transfer.
#define LARGE_RX 4096
int ReceiveFile(COM com, const char *filename)
{
CPARAM param;
ComParam(com, ¶m);
if(ComRxQ(com, LARGE_RX) != LARGE_RX)
return(-1);
... transfer file here
/* Restore original size */
if(ComRxQ(com, param.rxQ) != param.rxQ)
return(-2);
else
return(0);
}
4-14
ComTxQ
------------------------------------------------------------------
Function Resizes the specified serial port's transmit queue.
Syntax #include "cport.h"
unsigned ComTxQ(COM, unsigned size);
Parameters
COM - Handle of the serial port.
size - New transmit queue size.
Remarks ComTxQ resizes the specified serial port's transmit queue. The
memory currently allocated for the transmit queue is freed, and
new memory is allocated. If ComTxQ is unable to allocate the
specified amount memory, it will try to reallocate memory for
the previous size. ComTxQ returns the new queue size. If memory
was successfully allocated for the new size, the return value
will be size. If the previous size is reallocated, the return
value will be the previous size. If no memory could be
allocated, ComTxQ returns zero.
No data can be transmitted while the new transmit queue is
being resized. However, data to the receive queue will
continue to be received normally.
Return value ComTxQ returns the new transmit queue size.
See also ComRxQ, ComOpen, ComOpenS
Example Enlarge the transmit queue for a file transfer.
#define LARGE_TX 4096
int TransmitFile(COM com, const char *filename)
{
CPARAM param;
ComParam(com, ¶m);
if(ComTxQ(com, LARGE_TX) != LARGE_TX)
return(-1);
... transfer file here
/* Restore original size */
if(ComTxQ(com, param.txQ) != param.txQ)
return(-2);
else
return(0);
}
4-15
ComTx
------------------------------------------------------------------
Function Transmitter control.
Syntax #include "cport.h"
int ComTx(COM, int cmnd);
Parameters
COM - Handle of the serial port.
cmnd - Determines the action to be taken on the transmitter See Table
A-9 in Appendix A for a list of transmitter options.
Remarks ComTx allows advanced control of the Cport transmitter The
transmitter can be turned on and off to suspend and resume
transmissions. This function can be very useful when
implementing your own handshaking scheme. In addition, it can
inform the output functions to transmit directly when the
transmitter is turned off.
Return value ComTx returns the previous status of the transmitter
See also ComHandshake, ComOpenS, ComParam
Example Put a priority character directly to the serial port.
void PriorityPutc(COM com, char c)
{
int tx;
tx = ComTx(com, TX_DIRECT | OFF);
ComPutc(com, c);
ComTx(com, tx); /* restore original state */
}
ComNS550
------------------------------------------------------------------
Function NS16550 UART setup.
Syntax #include "cport.h"
void ComNS550(COM, int trigger);
Parameters
COM - Handle of the serial port.
trigger - Trigger threshold for the UART receive fifo. See Table A-12 in
Appendix A for a list of trigger thresholds.
Remarks If Cport detects an NS16550 UART when a serial port is opened,
Cport automatically takes advantage of it's advanced
capabilities.
4-16
The receive fifo threshold is the number of bytes in the
receive fifo that will cause an interrupt to be generated. By
default, the receive fifo threshold is set to 14 bytes.
ComNS550 allows this receive fifo trigger threshold to be
changed.
See Also ComUart
Example If the specified serial port is an NS16550 set the trigger
level to 1 byte.
void SetThreshIf550(COM com)
{
if(ComUart(com) == NS16550)
ComNS550(com, T550_1);
}
ComTurbo
------------------------------------------------------------------
Function Disables/re-enables high priority interrupts.
Syntax #include "cport.h"
void ComTurbo(int options);
Parameters
options - Bit mask of options. See Table A-6 in Appendix A for possible
options.
Remarks During high speed data exchanges, certain events that cause
high priority interrupts can inhibit serial communications and
possibly cause (over run) errors. This is especially true of
the timer, which periodically uses extra time and the
keyboard, if keys are pressed.
ComTurbo disables selected high priority interrupts or
restores all of them. The high priority interrupts should
never be disabled permanently or for long periods of time. The
timer interrupt is not actually disabled but diverted,
allowing the system clock to continue to update. All other
options are actually disabled when specified.
Example Disable the keyboard and divert the timer while a block is
transferred at high speed.
#include <time.h>
#define BLK_SZ 128
4-17
int GetBlock(COM com, byte* block, clock_t timeout)
{
int rv;
/* assume 115200 baud
*/
ComTurbo(TIMER | KEYBOARD);
timeout += clock();
while(ComLenRx(com) < BLK_SZ)
{
if(clock() > timeout)
{
ComTurbo(OFF);
return(0);
}
}
rv = ComIn(com, block, BLK_SZ);
ComTurbo(OFF);
return(rv);
}
4-18
Input Functions
---------------
Basic
ComGetc gets a character from the receive queue.
ComGets gets a string of characters from the receive.
ComIn gets a block of data from the receive queue.
ComFlushRx flushes the receive queue and receiver.
ComLenRx calculates the number of characters/bytes in the receive queue.
Intermediate
ComPeek returns a copy of the head character/byte without removing it
from the receive queue.
ComRxScan scans the receive queue for a specified character.
4-19
ComGetc
------------------------------------------------------------------
Function Fetches a character from the specified serial port's receive
queue.
Syntax #include "cport.h"
char ComGetc(COM);
Remarks ComGetc fetches the head character from the specified serial
port's receive queue. If there are no characters in the
receive queue, ComGetc returns a NULL character ('\0').
Parameters
COM - Handle of the serial port.
Return value If successful, ComGetc returns the character from the receive
queue. If it fails, it returns a NULL character ('\0').
See also ComPutc, ComGets, ComIn, ComPeek
Example Get a character from the modem and test if it is a start of
header control character.
#define SOH 1
int CheckForSOH(COM modem)
{
char c;
c = ComGetc(modem);
return(c == SOH);
}
ComGets
------------------------------------------------------------------
Function Fetches a string of characters from the specified serial
port's receive queue.
Syntax #include "cport.h"
char *ComGets(COM, char *str, int maxc, char termc);
Parameters
COM - Handle of the serial port.
str - Pointer to the buffer where the string of characters will be
stored.
maxc - Maximum number of characters to fetch.
termc - Termination character. ComGets will return if this character
is encountered.
Remarks ComGets fetches a string of characters from the specified
serial port's receive queue. The string will be stored in str.
Str must be at least maxc + 1 characters long to allow for the
4-20
NULL terminator. ComGets will return on the first occurrence
of one of three conditions: 1) the character termc is
encountered; 2) maxc characters are reached; or 3) no more
characters are available in the receive queue.
Return value ComGets returns a pointer to the NULL terminated string.
See also ComPuts, ComGetc, ComIn, ComLenRx
Example Get a measurement from the specified instrument if one is
ready.
#define MEAS_SIZ 24
char* GetMeasurment(COM instrument, char* buf)
{
if(ComLenRx(instrument) > MEAS_SIZ)
return(ComGets(instrument, buf, MEAS_SIZ, '\n'));
else
return(NULL);
}
ComIn
------------------------------------------------------------------
Function Fetches a block of bytes from the specified serial port's
receive queue.
Syntax #include "cport.h"
unsigned ComIn(COM, void *abyte, unsigned nbyte);
Parameters
COM - Handle of the serial port.
abyte - Pointer to a buffer where the block of bytes will be stored.
nbyte - Number of bytes to get from the receive queue.
Remarks ComIn fetches a block of bytes from the specified serial
port's the receive queue and stores it in abyte. ComIn will
always fetch num_byte bytes unless not enough bytes are
available. ComIn is well suited for receiving binary data.
Return value ComIn returns the number of bytes actually fetched.
See also ComOut, ComGetc, ComGets, ComLenRx
4-21
Example Get a block of 1024 bytes from the serial port.
#include <time.h>
#define BLK_SZ 1024
#define TIMEOUT -1
int GetBlock(COM datalink, byte* buf, clock_t timeout)
{
timeout += clock();
while(ComLenRx(datalink) < BLK_SZ)
{
if(clock() > timeout)
return(TIMEOUT);
}
return(ComIn(datalink, buf, BLK_SZ));
}
ComFlushRx
------------------------------------------------------------------
Function Flushes the specified serial port's receiver and receive
queue.
Syntax #include "cport.h"
void ComFlushRx(COM);
Parameters
COM - Handle of the serial port.
Remarks ComFlushRx deletes the specified serial port's receive queue
and the UART of any existing characters/bytes.
See also ComLenRx, ComFlushTx
Example If a receive flush command is in order, flush the receiver.
void RemoteCommand(COM com, int command)
{
switch(command)
{
case TX_FLUSH:
ComFlushTx(com);
break;
case RX_FLUSH:
ComFlushRx(com);
break;
...continued
}
}
4-22
ComLenRx
------------------------------------------------------------------
Function Calculates the number of characters/bytes in the specified
serial port's receive queue.
Syntax #include "cport.h"
unsigned ComLenRx(COM);
Parameters
COM - Handle of the serial port.
Remarks ComLenRx calculates the number of characters/bytes in the
specified serial port's receive queue.
Return value ComLenRx returns the number of characters/bytes residing
in the receive queue.
See also ComFlushRx, ComLenTx
Example Get a measurement from the specified instrument if one is
ready.
#define MEAS_SIZ 24
char* GetMeasurment(COM instrument, char* buf)
{
if(ComLenRx(instrument) > MEAS_SIZ)
{
ComGets(instrument, buf, MEAS_SIZ, '\n');
return(buf);
}
else
return(NULL);
}
ComPeek
------------------------------------------------------------------
Function Fetches a copy of the head character from the specified
serial port's receive queue.
Syntax #include "cport.h"
char ComPeek(COM);
Parameters
COM - Handle of the serial port.
Remarks ComPeek fetches a copy of the head character from the
specified serial port's receive queue. ComPeek will not
remove the character from the queue.
Return value ComPeek returns the copy of the head character.
4-23
See also ComGetc, ComRxScan
Example Get the head character, if it is a control character.
#include <ctype.h>
char GetIfControl(COM com)
{
char peek;
peek = ComPeek(com);
if(iscntrl(peek))
return(ComGetc(com));
else
return('\0');
}
ComRxScan
------------------------------------------------------------------
Function Scans the receive queue of the specified serial port for a
specific character.
Syntax #include "cport.h"
unsigned ComRxScan(COM, char c);
Parameters
COM - Handle of the serial port.
c - Character to scan for.
Remarks ComRxScan searches for the character c in the specified serial
port's receive queue. If the character is not found, ComRxScan
returns a zero. Otherwise it returns the offset into the
receive queue of the first occurrence of c starting at 1 for
the first character. This is the number of characters that
must be fetched to get all data up to and including the
character scanned for.
Return value ComRxScan returns the offset into the receive queue to the
first occurrence of c. If c does not exist, ComRxScan
returns a zero.
See also ComPeek
4-24
Example Get the next line terminated with a '\n'.
char *GetLine(COM com, char *buffer)
{
int n;
n = ComRxScan(com, '\n');
if(n > 0 && n < 80)
return(ComGets(com, buffer, n, '\n'));
else
return(NULL);
}
Example Get the next message terminated with a EOT control character.
#define EOT 0x4
int GetMessage(COM com, byte *buffer)
{
int n;
n = ComRxScan(com, EOT);
if(n > 0 && n < 80)
return(ComIn(com, buffer, n));
else
return(0);
}
4-25
Output Functions
----------------
Basic
ComPutc puts a character to the transmit queue.
ComPuts puts a string of characters to the transmit queue.
ComOut puts a block of data to the transmit queue.
ComFlushTx flushes the transmit queue and transmitter.
ComLenTx calculates the number of characters in the transmit queue.
Advanced
ComTxWait pauses program execution until the transmitter has emptied.
4-26
ComPutc
------------------------------------------------------------------
Function Puts a character into the specified serial port's transmit
queue.
Syntax #include "cport.h"
int ComPutc(COM, char c);
Parameters
COM - Handle of the serial port.
c - Character to be put into the transmit queue.
Remarks ComPutc puts a character into the specified serial port's
transmit queue to be transmitted. If the transmit queue is
full, the character is not put and ComPutc returns a 0.
Return value On success, ComPutc returns a 1. If it fails, it returns 0.
See also ComGetc, ComPuts, ComOut
Example Echo the keyboard to the serial port when fetching a keystroke.
#include <conio.h>
static COM echo;
char GetKey(void)
{
char c;
if(kbhit())
{
c = getch();
ComPutc(echo, c);
return(c);
}
else
return('\0');
}
ComPuts
------------------------------------------------------------------
Function Puts a string of characters into the specified serial port's
transmit queue.
Syntax #include "cport.h"
int ComPuts(COM, const char *str);
4-27
Parameters
COM - Handle of the serial port.
str - Pointer to the string to be put into the transmit queue.
Remarks ComPuts puts the string str into the specified serial port's
transmit queue to be transmitted. If the transmit queue
becomes full, ComPuts will not attempt to put any more
characters in the queue.
Return value ComPuts returns the actual number of characters put into
the transmit queue.
See also ComGets, ComPutc, ComOut
Example Dial a number on the modem.
#include <string.h>
void ModDial(COM modem, const char* number)
{
char dial[24] = "ATDT";
strcat(dial, number);
strcat(dial, "\r");
ComPuts(modem, dial);
}
ComOut
------------------------------------------------------------------
Function Puts a block of bytes into the specified serial port's
transmit queue.
Syntax #include "cport.h"
unsigned ComOut(COM, const void *abyte, unsigned nbyte);
Parameters
COM - Handle of the serial port.
abyte - Pointer to the block of data to be put into the transmit
queue.
nbyte - Number of bytes to be put into the transmit queue.
Remarks ComOut puts the block of bytes pointed to by abyte into the
specified serial port's transmit queue to be transmitted.
Return value ComOut returns the number of bytes actually put into the
transmit queue.
See also ComIn, ComPutc, ComPuts
4-28
Example Send a block of 128 bytes to the transmitter.
#define BLK_SZ 128
int SendBlock(COM com, const byte* block)
{
int rv;
rv = ComOut(com, block, BLK_SZ);
if(rv < BLK_SZ)
return(-1);
else
return(0);
}
ComFlushTx
------------------------------------------------------------------
Function Flushes the specified serial port's transmit queue.
Syntax #include "cport.h"
void ComFlushTx(COM);
Parameters
COM - Handle of the serial port.
Remarks ComFlushTx deletes any existing characters in the specified
serial port's transmit queue.
See also ComFlushRx, ComLenTx
Example If a transmit flush command is in order, flush the transmit
queue.
void RemoteCommand(COM com, int command)
{
switch(command)
{
case TX_FLUSH:
ComFlushTx(com);
break;
case RX_FLUSH:
ComFlushRx(com);
break;
...continued
}
}
4-29
ComLenTx
------------------------------------------------------------------
Function Calculates the number of characters/bytes in the specified
serial port's transmit queue.
Syntax #include "cport.h"
unsigned ComLenTx(COM);
Parameters
COM - Handle of the serial port.
Remarks ComLenTx calculates the number of characters/bytes in the
specified serial port's transmit queue.
Return value ComLenTx returns the number of characters/bytes in the
transmit queue.
See also ComLenRx, ComFlushTx
Example Check if the transmitter has reached 3/4 of its capacity.
#define TX_SIZE 1024
int IsAboveThresh(COM sprinter)
{
return(ComLenTx(sprinter) > (TX_SIZE * 3 / 4));
}
ComTxWait
------------------------------------------------------------------
Function Waits for the specified serial port's transmitter to empty
Syntax #include "cport.h"
void ComTxWait(COM);
Parameters
COM - Handle of the serial port.
Remarks When a transmit queue becomes empty, the UART may not have
actually transmitted the last of the bytes. A program may need
to know when all the data has actually been transmitted so
that it may, for example, change the state of the hardware
lines during half duplex communications. ComTxWait will return
after the UART has been emptied of data.
See Also ComLenTx
4-30
Example Send a string to a half duplex device. This examples assumes
that the device is monitoring our RTS line to determine a
transmit or receive state.
void SendMessage(COM device, const char* msg)
{
ComRts(device, ON);
ComPuts(device, msg);
while(ComLenTx(device));
ComTxWait(device);
ComRts(device, OFF);
}
4-31
Status Functions
----------------
Basic
ComError detects hardware and software errors.
Intermediate
ComStatus returns the status of the software and input hardware lines.
ComRts controls the RTS output line.
ComDtr controls the DTR output line.
Advanced
ComOut1 controls the general purpose OUT1 output line.
ComUart determines what type of UART chip is residing at a serial port.
4-32
ComError
------------------------------------------------------------------
Function Determines if any errors have occurred on the specified
serial port since the last call to ComError.
Syntax #include "cport.h"
unsigned ComError(COM);
Parameters
COM - Handle of the serial port.
Remarks ComError determines if any errors are pending on the specified
serial port. After a call to ComError, the errors are cleared.
ComError returns a bit ORed error word. See Table A-7 in
Appendix A for a list of bit definitions.
Return value If an error has occurred, ComError returns an error word.
If no errors have occurred, it returns a 0.
See also ComStatus
Example Determine the source of the error if one has occurred.
#define HARDWARE (PARITY | FRAMING | BREAK | RX_FIFO)
void CheckForErrors(COM dvm)
{
unsigned err;
if((err = ComError(dvm)) == 0)
return;
else if(err & OVERUN)
{
/* over run error */
}
else if(err & HARDWARE)
{
/* hardware errors */
}
else if(err & (TXFULL | RXFULL))
{
/* queue errors */
}
}
4-33
ComStatus
------------------------------------------------------------------
Function Retrieves the status of the specified serial port's software
and hardware lines.
Syntax #include "cport.h"
unsigned ComStatus(COM);
Parameters
COM - Handle of the serial port.
Remarks ComStatus retrieves the status of the specified serial port's
software and hardware lines. ComStatus returns a bit ORed
status word. See Table A-8 in Appendix A for a list of bit
definitions.
Return value ComStatus returns the status word of the software and
hardware lines.
See also ComError, ComRts, ComDtr
Example Test if the modem is powered up and ready.
#include <dos.h>
int CheckModem(COM modem)
{
ComDtr(modem, ON);
delay(40);
return((ComStatus(modem) & DSR) != 0);
}
ComRts
------------------------------------------------------------------
Function Asserts or inhibits the specified serial port's Request to
Send line.
Syntax #include "cport.h"
void ComRts(COM, byte on_off);
Parameters
COM - Handle of the serial port.
on_off - Determines whether RTS is to be asserted or inhibited. See
Table A-10 in Appendix A.
Remarks ComRts asserts or inhibits the specified serial port's RTS
line depending on the value of on_off. If the value of on_off
is ON, RTS is asserted. If the value of on_off is OFF, RTS is
inhibited. In many cases, this signal will be looked at by the
4-34
remote device to determine if it is safe to transmit. This
gives the programmer the ability to turn off the remote
device's transmitter.
NOTE: ComRts should never be called when RTS hardware
handshaking is enabled.
See also ComDtr, ComStatus, ComHandshake
Example Put the device in an on or off line state. (Assumes the
remote device will not send data without our RTS asserted)
void OffLine(COM device)
{
ComRts(device, OFF);
}
void OnLine(COM device)
{
ComRts(device, ON);
}
ComDtr
------------------------------------------------------------------
Function Asserts or inhibits the specified serial port's Data
Terminal Ready line.
Syntax #include "cport.h"
void ComDtr(COM, byte on_off);
Parameters
COM - Handle of the serial port.
on_off - Determines whether DTR is to be asserted or inhibited. See
Table A-10 in Appendix A.
Remarks ComDtr asserts or inhibits the specified serial port's DTR
line depending on the value of on_off. If the value of on_off
is ON, DTR is asserted. If the value of on_off is OFF, DTR is
inhibited. In many cases, this signal will be looked at by the
remote device to determine if it is safe to transmit. This
gives the programmer the ability to turn off the remote
device's transmitter.
NOTE: ComDtr should never be called when DTR hardware
handshaking is enabled.
See also ComRts, ComStatus, ComHandshake
4-35
Example Put the device in an on or off line state. (Assumes the remote
device will not send data without our DTR asserted).
void OffLine(COM device)
{
ComDtr(device, OFF);
}
void OnLine(COM device)
{
ComDtr(device, ON);
}
ComOut1
------------------------------------------------------------------
Function Asserts or inhibits the specified serial port's Out1 line.
Syntax #include "cport.h"
void ComOut1(COM, byte on_off);
Parameters
COM - Handle of the serial port.
on_off - Determines whether OUT1 is to be asserted or inhibited. See
Table A-10 in Appendix A.
Remarks ComOut1 asserts or inhibits the specified serial port's general
purpose OUT1 line depending on the value of on_off. If the
value of on_off is ON, OUT1 is asserted. If the value of
on_off is OFF, OUT1 is inhibited. OUT1 is a general purpose
output sometimes utilized by a device for a special feature
or reset.
See also ComRts, ComDtr
Example Reset a smart modem.
void SmartReset(COM modem)
{
ComOut1(modem, ON);
delay(50);
ComOut1(modem, OFF);
}
ComUart
------------------------------------------------------------------
Function Determines the type of UART at the specified serial port.
Syntax #include "cport.h"
int ComUart(COM);
4-36
Parameters
COM - Handle of the serial port.
Remarks ComUart determines the type of UART chip that resides at the
specified serial port. See Table A-11 in Appendix A for a list
of UART types.
Return value ComUart returns a value representative of the type of UART
that was detected.
See Also ComNS550
Example If the specified serial port has an NS16550 UART, set the
trigger level to 1 byte.
void SetThreshIf550(COM com)
{
if(ComUart(com) == NS16550)
ComNS550(com, T550_1);
}
4-37
Data Integrity
--------------
Intermediate
ComChecksum calculates a byte checksum of a block of data.
ComCrc16 calculates a 16 bit cyclic redundancy check (CRC) on a block
of data.
ComCrc32 calculates a 32 bit cyclic redundancy check (CRC) on a block
of data.
4-38
ComChecksum
------------------------------------------------------------------
Function Performs a byte checksum calculation on a block of data.
Syntax #include "cport.h"
byte ComChecksum(const void *abyte, unsigned nbyte);
Parameters
abyte - Pointer to the block on which the checksum is to be performed.
nbyte - Number of bytes in the block.
Remarks ComChecksum performs a byte checksum on the block of bytes
pointed to by abyte. The checksum is calculated by summing all
the bytes in the block.
Return value ComChecksum returns a one byte checksum.
See also ComCrc16, ComCrc32, ComIn, ComOut
Example Verify that the actual checksum matches the received checksum.
struct Xblock{
byte num;
byte _num;
byte data[128];
byte checksum;
}block;
int GetXblock(COM com, Xblock *block)
{
ComIn(com, block, sizeof(Xblock));
if((ComChecksum(block->data, 128) - block->checksum) != 0)
return(-1);
else
return(0);
}
ComCrc16
------------------------------------------------------------------
Function Performs a 16 bit cyclic redundancy check on a block of data.
Syntax #include "cport.h"
unsigned ComCrc16(const void *abyte, unsigned nbyte);
Parameters
abyte - Pointer to the block on which the 16 bit cyclic redundancy
check is to be performed.
nbyte - Number of bytes in the block.
4-39
Remarks ComCrc16 performs a 16 bit cyclic redundancy check on the
block of data pointed to by abyte.
Return value ComCrc16 returns the 16 bit CRC value.
See also ComCrc32, ComChecksum, ComIn, ComOut
Example Verify that the actual CRC matches the received CRC.
struct Xblock{
byte num;
byte _num;
byte data[128];
unsigned crc;
}block;
int GetXblock(COM com, Xblock *block)
{
ComIn(com, block, sizeof(Xblock));
/* Check the calculated CRC against the block's CRC.
*/
if(ComCrc16(block->data, 128) != block->crc)
return(-1);
else
return(0);
}
ComCrc32
------------------------------------------------------------------
Function Performs a 32 bit cyclic redundancy check on a block of data.
Syntax #include "cport.h"
unsigned long ComCrc32(const void *abyte, unsigned nbyte);
Parameters
abyte - Pointer to the block on which the 32 bit cyclic redundancy
check is to be performed.
nbyte - Number of bytes in the block.
Remarks ComCrc32 performs a 32 bit cyclic redundancy check on the
block of data pointed to by abyte.
Return value ComCrc32 returns the 32 bit CRC value.
See also ComCrc16, ComChecksum, ComIn, ComOut
4-40
Example Verify that the actual CRC matches the received CRC.
struct Packet
{
byte num;
byte data[1024];
unsigned long crc;
}packet;
int GetBlock(COM com, Packet* packet)
{
ComIn(com, packet, sizeof(Packet));
/* Check the calculated CRC against the packet's CRC.
*/
if(ComCrc32(packet->data, 1024) != packet->crc)
return(-1);
else
return(0);
}
4-41
Misc Functions
--------------
Advanced
ComSetBreak sets a break condition.
ComClrBreak clears a break condition.
ComPutScrtch writes to the UART's scratch register.
ComGetScrtch reads the UART's scratch register.
4-42
ComSetBreak
------------------------------------------------------------------
Function Set a break condition on the specified serial port.
Syntax #include "cport.h"
void ComSetBreak(COM);
Parameters
COM - Handle of the serial port.
Remarks ComSetBreak sets a break condition on the specified serial
port. The break condition will stay in effect until a
subsequent call to ComClrBreak is made.
See also ComClrBreak
Example If the an abort condition has been declared, set a break
condition. When it clears, release the break condition.
void Abort(COM com, int abrt)
{
static int brkflg;
if(abrt && !brkflg)
ComSetBreak(com);
else if(!abrt && brkflg)
ComClrBreak(com);
}
ComClrBreak
------------------------------------------------------------------
Function Clears a previously set break condition on the specified
serial port.
Syntax #include "cport.h"
void ComClrBreak(COM);
Parameters
COM - Handle of the serial port.
Remarks ComClrBreak clears a previously set break condition on the
specified serial port.
See also ComSetBreak
4-43
Example If the an abort condition has been declared, set a break
condition. When it clears, release the break condition.
void Abort(COM com, int abrt)
{
static int brkflg;
if(abrt && !brkflg)
ComSetBreak(com);
else if(!abrt && brkflg)
ComClrBreak(com);
}
ComPutScrtch
------------------------------------------------------------------
Function Writes a byte to the specified serial port's scratch register.
Syntax #include "cport.h"
void ComPutScrtch(COM, byte abyte);
Parameters
COM - Handle of the serial port.
abyte - The byte to be written to the scratch register.
Remarks ComPutScrtch writes the byte value abyte to the specified
serial port's UART scratch register. Not all UARTs have a
scratch register.
See also ComGetScrtch
Example Exchange a value with the scratch register.
byte ScratchExchange(COM com, byte value)
{
byte rv;
rv = ComGetScrtch(com); /* read the scratch register */
ComPutScrtch(com, value); /* write to the scratch register */
return(rv);
}
ComGetScrtch
------------------------------------------------------------------
Function Fetches the byte stored in the specified serial port's scratch
register.
Syntax #include "cport.h"
byte ComGetScrtch(COM);
4-44
Parameters
COM - Handle of the serial port.
Remarks ComGetScratch reads the byte in the specified serial port's
UART scratch register. Not all UARTs have a scratch register.
Return value ComGetScrtch returns the byte read from the UART scratch
register.
See also ComPutScrtch
Example Exchange a value with the scratch register.
byte ScratchExchange(COM com, byte value)
{
byte rv;
rv = ComGetScrtch(com); /* read the scratch register */
ComPutScrtch(com, value); /* write to the scratch register */
return(rv);
}
5-1
C++ Reference
=============
Control Functions
-----------------
Basic
Cport::Cport constructs serial port instance with either discrete
parameters or a structure of parameters.
Cport::operator int returns the results of constructing a serial port
instance.
Cport::Handshake determines if and what type of handshaking scheme
will be enabled and sets the receive queue threshold.
Intermediate
Cport::Param reports on the current parameters and handshaking under
which a serial port is currently operating.
Cport::Baud changes the baud rate.
Cport::Mode changes the word length, number of stop bits and parity.
Advanced
Cport::RxQ resizes the receive queue.
Cport::TxQ resizes the transmit queue.
Cport::Tx allows advanced control over the transmitter.
Cport::NS550 sets the receive fifo threshold of an NS16550 UART.
Cport::Turbo temporarily disables/re-enables selected high priority
interrupts that may impede high speed communications.
5-2
Cport::Cport
------------------------------------------------------------------
Function Constructor.
Syntax #include "cport.h"
Cport::Cport(unsigned id, int baud, byte mode = W8|S1|NONE,
unsigned rxQ = 1024, unsigned txQ = 512, byte htype = OFF);
or
Cport::Cport(unsigned id, int baud, byte mode, unsigned rxQ,
unsigned txQ, byte htype, unsigned thresh);
or
Cport::Cport(const CPARAM& param)
Parameters
id - Value that identifies the serial port. The upper 4 bits define
the interrupt request line, while the lower 12 bits define the
port address. This technique allows for possibility of custom
configurations. See Table A-1 in Appendix A for a list of
predefined values.
baud - Value that defines the baud rate. The actual value is the
baud rate divisor, which allows for the possibility of custom
baud rates. The baud rate divisor = f / (16 * baud rate) where
f is 1.8432e+6. See Table A-2 in Appendix A for a list of
predefined baud rate divisors.
mode - Bit ORed value defining the word length, number of stop bits
and the parity. See Table A-3 in Appendix A for a list of mode
components.
* rxQ - Size, in bytes, of the receive queue.
* txQ - Size, in bytes, of the transmit queue.
* Limited to 32K in small and medium memory models.
htype - Type of handshaking to be used. See Table A-5 in Appendix A
for a list of handshaking components.
thresh - Receive queue threshold.
Remarks The constructor creates an instance of the specified serial
port. If the constructor is unable to open the specified
serial port, the instance of the serial port will return an
error code when casted to an integer. If the port is
successfully opened, the instance will return a zero when
casted to an integer.
The 4 most significant bits in id represent the interrupt
vector. The lower 12 bits represent the port address.
Constants are provided to facilitate the formulation of the id
parameter. The COMx values will work in most cases, however,
5-3
the IRQx values can be ORed with the PORTx or BIOSx values to
produce other combinations. The PORTx values are actual port
addresses where the serial ports are normally located. The
BIOSx values are actually macros, which fetch the port address
from the BIOS data area.
The parameter baud is the baud rate divisor, that determines
the baud rate. Achieving baud rates above 19200 is largely
dependent on many variables, such as machine speed, cable
length, handshaking activity, degree bidirectional transfers,
number of open serial ports, the type UART(s) used and
activity of other hardware interrupts.
The parameter mode determines the word length, number of stop
bits and parity. Bits 0 and 1 determine the word length, bit 2
determines the number of stop bits, bit 3 enables parity and
bits 4 and 5 determine the type of parity check.
RxQ and txQ set the size of the receive and transmit queues
respectively. RxQ should be at least 4 times larger than the
largest string or block of data expected. TxQ can be set as
small as 1, but it is not recommended. In the small and medium
memory models where all data is limited to 64K, the size of
the queues are limited. In the compact and large memory
models, each queue can be as large as 64K -1 (65534 bytes).
See Also Cport::operator int
Example Open COM1 at 9600 baud with 8 bit words, 1 stop bit, no
parity, a 1024 byte receiver and a 512 byte transmitter.
int main(void)
{
Cport com1(COM1, B9600, W8|S1|NONE, 1024, 512);
if((int)com1 != NO_ERR)
{
switch(com1)
{
case RX_ALC:
case TX_ALC:
case GEN_ALC:
// allocation error
break;
case NO_UART:
// no UART
break;
default:
// all other errors
break;
}
}
...continued
5-4
Cport::operator int
------------------------------------------------------------------
Function Gets the error code from when the instance of the serial port
was constructed.
Syntax #include "cport.h"
Cport::operator int()
Remarks When an instance of a serial port is constructed, the
specified serial port is not necessarily successfully opened.
Cport::operator int is an integer typecast used for procuring
the error code from when an instance of the serial port was
constructed. The actual typecasting may or may not be
necessary, but is recommended.
Return value Cport::operator int returns an error code from when the
instance of the serial port was constructed. See Table A-4
in Appendix A for a list of possible return values.
See Also Cport::Cport
Example Check for errors after instance of a serial port is
constructed.
int main(void)
{
Cport com1(COM1, B9600, W8|S1|NONE, 1024, 512);
// The instance 'com1' is casted to an int to procure the
// error code.
//
if((int)com1 != NO_ERR)
{
switch(com1)
{
case RX_ALC:
case TX_ALC:
case GEN_ALC:
// allocation error
break;
case NO_UART:
// no UART
break;
default:
// all other errors
break;
}
}
...continued
5-5
Cport::Handshake
------------------------------------------------------------------
Function Enables or disables handshaking (flow control ) for a serial
port.
Syntax #include "cport.h"
void Cport::Handshake(byte htype, unsigned thresh);
Parameters
htype - Type of handshaking to be used. See Table A-5 in Appendix A
for a list of handshaking components.
thresh - Receive queue threshold.
Remarks Cport::Handshake enables or disables software and/or hardware
handshaking for the serial port instance. In software
handshaking, XON and XOFF characters are used to suspend and
resume communications. Hardware handshaking uses any or all of
the DTR, DSR, RTS, CTS and DCD lines to suspend and resume
communications. Thresh determines when the receiver will
assert and inhibit the corresponding handshaking. If no
receive handshaking is specified (RTS, DTR or S_RX), the
threshold is not used and may be set to zero.
See also Cport::Param, Cport::Cport, Cport::Tx
Example If COM1 is successfully opened, turn on some hardware
handshaking and set the receiver threshold to 3/4 of the
receiver's full size. The transmitter will not transmit unless
both DSR and DCD are asserted. The receiver will inhibit DTR
if the receive queue length exceeds the threshold.
int main(void)
{
Cport com1(COM1, B9600, W8|S1|NONE, 1024, 512);
if((int)com1 != NO_ERR)
{
// error
}
com1.Handshake(DSR|DTR|DCD, 768);
...continued
return(0);
}
5-6
Cport::Param
------------------------------------------------------------------
Function Retrieves the parameters of a serial port.
Syntax #include "cport.h"
Cport::Param(CPARAM& param)
Parameters
param - Reference to a type CPARAM where the parameters will be
stored.
Remarks Cport::Param retrieves the parameters and handshaking status
of the serial port instance and stores them in a type CPARAM.
See also CPARAM, Cport::Cport
Example Create an instance of a serial port with the same
configuration as one that already exists.
Cport OpenCopy(int id, Cport& copyme)
{
CPARAM param;
copyme.Param(param);
param.id = id;
return(Cport(param));
}
Cport::Baud
------------------------------------------------------------------
Function Changes the baud rate of a serial port.
Syntax #include "cport.h"
void Cport::Baud(int baud);
Parameters
baud - Value that defines the baud rate. The actual value is the
baud rate divisor, which allows for possibility of custom baud
rates. The baud rate divisor = f / (16 * baud rate) where
f is 1.8432e+6. See Table A-2 in Appendix A for a list of
predefined baud rate divisors.
Remarks Cport::Baud changes the baud rate of the serial port instance.
The parameter baud is the baud rate divisor that determines
the baud rate.
See also Cport::Cport, Cport::Param, Cport::Mode
5-7
Example Set the specified serial port to a new baud rate.
#define NBAUD 4
int SetBaud(Cport& com, unsigned n)
{
int baud[NBAUD] = { B9600, B2400, B1200, B300 };
if(n < NBAUD)
{
com.Baud(baud[n]);
return(0);
}
else
return(-1);
}
Cport::Mode
------------------------------------------------------------------
Function Changes the word length, number of stop bits and parity of a
serial port.
Syntax #include "cport.h"
void Cport::Mode(byte mode);
Parameters
mode - Bit ORed value defining the word length, number of stop bits
and the parity. See Table A-3 in Appendix A for a list of mode
components.
Remarks Cport::Mode changes the word length, number of stop bits and
parity of the serial port instance. The parameter mode
determines the word length, number of stop bits and parity of
the serial port instance. Bits 0 and 1 determine the word
length, bit 2 determines the number of stop bits, bit 3 enables
parity and bits 4 and 5 determine the type of parity check.
See also Cport::Cport, Cport::Param, Cport::Baud
Example Set the serial port to a new mode.
#define NMODE 2
int SetMode(Cport& com, unsigned n)
{
int mode[NMODE] = { W8|S1|NONE, W7|S1|EVEN };
if(n < NMODE)
{
com.Mode(mode[n]);
return(0);
}
return(-1);
}
5-8
Cport::RxQ
------------------------------------------------------------------
Function Resizes the receive queue of a serial port.
Syntax #include "cport.h"
unsigned Cport::RxQ(unsigned size);
Parameters
size - New receive queue size.
Remarks Cport::RxQ resizes the receive queue of the serial port
instance. The memory currently allocated for the receive queue
is freed and new memory is allocated. If Cport::RxQ is unable
to allocate the specified amount memory, it will try to
reallocate memory for the previous size. Cport::RxQ returns
the new queue size. If memory was successfully allocated for
the new size, the return value will be size. If the previous
size is reallocated, the return value will be the previous
size. If no memory could be allocated, Cport::RxQ returns
zero.
No data can be received while the new receive queue is being
resized. However, data in the transmit queue will continue to
be transmitted normally.
Return value Cport::RxQ returns the new receive queue size.
See also Cport::TxQ, Cport::Cport
Example Enlarge the receive queue for a file transfer.
#define LARGE_RX 4096
int ReceiveFile(Cport& com, const char *filename)
{
CPARAM param;
com.Param(param);
if(com.RxQ(LARGE_RX) != LARGE_RX)
return(-1);
... transfer file here
// Restore original size
if(com.RxQ(param.rxQ) != param.rxQ)
return(-2);
else
return(0);
}
5-9
Cport::TxQ
------------------------------------------------------------------
Function Resizes the transmit queue of a serial port.
Syntax #include "cport.h"
unsigned Cport::TxQ(unsigned size);
Parameters
size - New transmit queue size.
Remarks Cport::TxQ resizes the transmit queue of the serial port
instance. The memory currently allocated for the transmit
queue is freed and new memory is allocated. If Cport::TxQ is
unable to allocate the specified amount memory, it will try
to reallocate memory for the previous size. Cport::TxQ returns
the new queue size. If memory was successfully allocated for
the new size, the return value will be size. If the previous
size is reallocated, the return value will be the previous
size. If no memory could be allocated, Cport::TxQ returns zero.
No data can be transmitted while the new transmit queue is
being resized. However, data in the receive queue will
continue to be received normally.
Return value ComTxQ returns the new transmit queue size.
See also Cport::RxQ, Cport::Cport
Example Enlarge the transmit queue for a file transfer.
#define LARGE_TX 4096
int TransmitFile(Cport& com, const char *filename)
{
CPARAM param;
com.Param(param);
if(com.TxQ(LARGE_TX) != LARGE_TX)
return(-1);
... transfer file here
// Restore original size
if(com.TxQ(param.txQ) != param.txQ)
return(-2);
else
return(0);
}
5-10
Cport::Tx
------------------------------------------------------------------
Function Transmitter control.
Syntax #include "cport.h"
int Cport::Tx(int cmnd);
Parameters
cmnd - Determines the action to be taken on the transmitter See
Table A-9 in Appendix A for a list of transmitter options.
Remarks Cport::Tx allows advanced control of the Cport transmitter
The transmitter can be turned off and on to suspend and resume
transmissions. This function can be very useful when
implementing your own handshaking scheme. In addition, it can
inform the output functions to transmit directly when the
transmitter is turned off.
Return value Cport::Tx returns the previous status of the transmitter.
See also Cport::Handshake, Cport::Cport, Cport::Param
Example Put a priority character directly to the serial port.
void PriorityPutc(Cport& com, char c)
{
int tx;
tx = com.Tx(TX_DIRECT | OFF);
com.Put(c);
com.Tx(tx);
}
Cport::NS550
------------------------------------------------------------------
Function NS16550 UART setup.
Syntax #include "cport.h"
void Cport::NS550(int trigger);
Parameters
trigger - Trigger threshold for the UART receive fifo. See Table A-12
in Appendix A for a list of trigger levels.
Remarks If Cport detects an NS16550 UART when a serial port is opened,
Cport automatically takes advantage of it's advanced capabilities.
The receive fifo threshold is the number of bytes in the receive
fifo that will cause an interrupt to be generated. By default,
the receive fifo threshold is set to 14 bytes. Cport::NS550
allows this receive fifo trigger threshold to be changed.
5-11
See Also Cport::Uart
Example If the specified serial port is an NS16550, set the trigger
level to 1 byte.
void SetThreshIf550(Cport& com)
{
if(com.Uart() == NS16550)
com.NS550(T550_1);
}
Cport::Turbo
------------------------------------------------------------------
Function Disables/re-enables high priority interrupts.
Syntax #include "cport.h"
static void Cport::Turbo(int options);
Parameters
options - Bit mask of options. See Table A-6 in Appendix A for a list
of turbo options.
Remarks During high speed data exchanges certain events that cause
high priority interrupts can impede serial communications and
possibly cause (over run) errors. This is especially true of
the timer, which periodically uses extra time, and the
keyboard, if keys are pressed.
Cport::Turbo disables selected high priority interrupts or
restores all of them. The high priority interrupts should
never be disabled permanently or for long periods of time. The
timer interrupt is not actually disabled but divert, allowing
the system clock to continue to update. All other options are
actually disabled when specified. Cport::Turbo is a static
function. Although not very useful, it can be called prior to
and/or independent of any instance of a serial port by
specifying it's full name: Cport::Turbo(options).
Example Disable the keyboard and divert the timer while a block is
transferred at high speed.
5-12
#include <time.h>
#define BLK_SZ 128
int GetBlock(Cport& com, byte* block, clock_t timeout)
{
int rv;
// assume 115200 baud
//
com.Turbo(TIMER | KEYBOARD);
timeout += clock();
while(com.LenRx() < BLK_SZ)
{
if(clock() > timeout)
{
com.Turbo(OFF);
return(0);
}
}
rv = com.In(block, BLK_SZ);
com.Turbo(OFF);
return(rv);
}
5-13
Input Functions
---------------
Basic
Cport::Get gets a character or string of characters from the receive
queue.
Cport::In gets a block of data from the receive queue.
Cport::FlushRx flushes the receive queue and receiver.
Cport::LenRx calculates the number of characters/bytes in the receive
queue.
Intermediate
Cport::Peek returns a copy of the head character/byte without removing
it from the receive queue.
Cport::RxScan scans the receive queue for a specified character.
5-14
Cport::Get
------------------------------------------------------------------
Function Fetches a character or string of characters from a serial
port's receive queue.
Syntax #include "cport.h"
char* Cport::Get(char *str, int maxc, char termc = '\n');
or
char Cport::Get();
Parameters
str - Pointer to the buffer where the string of characters will be
stored.
maxc - Maximum number of characters to fetch.
termc - Termination character. Cport::Get will return if this
character is encountered.
Remarks Cport::Get fetches a character or string of characters from
the serial port instance's receive queue.
If Cport::Get is called with no parameters, it will fetch one
character from the head of the serial port instance's receive
queue. If there are no characters in the receive queue,
Cport::Get returns a NULL character ('\0').
If Cport::Get is called with parameters, it fetches a string
of characters from the serial port instance's receive queue.
The string will be stored in str. Str must be at least
maxc + 1 characters long to allow for the NULL terminator.
Cport::Get will return on the first occurrence of one of
three conditions: 1) the character termc is encountered;
2) maxc characters are reached; or 3) no more characters are
available in the receive queue.
Return value When Cport:Get is called with no parameters, on success
it returns the character from the receive queue. If it
fails, it returns a NULL character ('\0'). When it is called
with parameters, Cport::Get returns a pointer to the NULL
terminated string.
See also Cport::In, Cport::LenRx, Cport::Put
5-15
Example Get a measurement from the specified instrument if one is
ready.
#define MEAS_SIZ 24
char* GetMeasurment(Cport& instrument, char* buf)
{
if(instrument.LenRx() > MEAS_SIZ)
{
instrument.Get(buf, MEAS_SIZ, '\n');
return(buf);
}
else
return(NULL);
}
Example Get a character from the modem and test if it is a start of
header control character.
#define SOH 1
int CheckForSOH(Cport& modem)
{
char c;
c = modem.Get();
return(c == SOH);
}
Cport::In
------------------------------------------------------------------
Function Fetches a block of bytes from a serial port's receive queue.
Syntax #include "cport.h"
unsigned Cport::In(void *abyte, unsigned nbyte);
Parameters
abyte - Pointer to a buffer where the block of bytes will be stored.
nbyte - Number of bytes to get from the receive queue.
Remarks Cport::In fetches a block of bytes from the serial port
instance's receive queue and stores it in abyte. Cport::In
will always fetch num_byte bytes unless not enough bytes are
available. Cport::In is well suited for receiving binary data.
Return value Cport::In returns the number of bytes actually fetched.
See also Cport::Out, Cport::Get, Cport::LenRx
5-16
Example Get a block of 1024 bytes from the serial port.
#include <time.h>
#define BLK_SZ 1024
#define TIMEOUT -1
int GetBlock(Cport& datalink, byte* buf, clock_t timeout)
{
timeout += clock();
while(datalink.LenRx() < BLK_SZ)
{
if(clock() > timeout)
return(TIMEOUT);
}
return(datalink.In(buf, BLK_SZ));
}
Cport::FlushRx
------------------------------------------------------------------
Function Flushes a serial port's receiver and receive queue.
Syntax #include "cport.h"
void Cport::FlushRx();
Remarks Cport::FlushRx deletes all existing characters/bytes in the
serial port instance's receive queue and receiver.
See also Cport::LenRx, Cport::FlushTx
Example If a receive flush command is in order, flush the receiver.
void RemoteCommand(Cport& com, int command)
{
switch(command)
{
case TX_FLUSH:
com.FlushTx();
break;
case RX_FLUSH:
com.FlushRx();
break;
...continued
}
}
5-17
Cport::LenRx
------------------------------------------------------------------
Function Calculates the number of characters/bytes in the receive
queue of a serial port.
Syntax #include "cport.h"
unsigned Cport::LenRx();
Remarks Cport::LenRx calculates the number of characters/bytes
in the receive queue of the serial port instance.
Return value Cport::LenRx returns the number of characters/bytes
residing in the receive queue.
See also Cport::FlushRx, Cport::LenTx
Example Get a measurement from the specified instrument if one is
ready.
#define MEAS_SIZ 24
char* GetMeasurment(Cport& instrument, char* buf)
{
if(instrument.LenRx() > MEAS_SIZ)
{
instrument.Get(buf, MEAS_SIZ, '\n');
return(buf);
}
else
return(NULL);
}
Cport::Peek
------------------------------------------------------------------
Function Fetches a copy of the head character from a serial port's
receive queue.
Syntax #include "cport.h"
char Cport::Peek();
Remarks Cport::Peek fetches a copy of the head character from the
serial port instance's receive queue. Cport::Peek will not
remove the character from the queue.
Return value Cport::Peek returns the copy of the head character.
See also Cport::Get, Cport::RxScan
5-18
Example Get the head character if it is a control character.
#include <ctype.h>
char GetIfControl(Cport& com)
{
char peek;
peek = com.Peek();
if(iscntrl(peek))
return(com.Get());
else
return('\0');
}
Cport::RxScan
------------------------------------------------------------------
Function Scans the receive queue of a serial port for a specific
character.
Syntax #include "cport.h"
unsigned Cport::RxScan(char c);
Parameters
c - Character to scan for.
Remarks Cport::RxScan searches for the character c in the serial port
instance's receive queue. If the character is not found,
Cport::RxScan returns a zero. Otherwise, it returns the offset
into the receive queue of the first occurrence of c starting
at 1 for the head character. This is the number of characters
that must be fetched to get all data up to and including the
character scanned for.
Return value Cport::Peek returns the offset into the receive queue to
the first occurrence of c. If c does not exist,
Cport::RxScan returns a zero.
See also Cport::Peek, Cport::Get
Example Get the next line terminated with a '\n'.
char *GetLine(Cport& com, char *buffer)
{
int n;
n = com.RxScan('\n');
if(n > 0 && n < 80)
return(com.Get(buffer, n, '\n'));
else
return(NULL);
}
5-19
Output Functions
----------------
Basic
Cport::Put puts a character or a string of characters to the transmit
queue.
Cport::Out puts a block of data to the transmit queue.
Cport::FlushTx flushes the transmit queue and transmitter.
Cport::LenTx calculates the number of characters/bytes in the transmit
queue.
Advanced
Cport::TxWait pauses program execution until the transmitter has emptied.
5-20
Cport::Put
------------------------------------------------------------------
Function Puts a character or a string of characters into the serial
port's transmit queue.
Syntax #include "cport.h"
int Cport::Put(const char *str);
or
int Cport::Put(char c);
Parameters
str - Pointer to the string to be put into the transmit queue.
c - Character to be put into the transmit queue.
Remarks Cport::Put puts a character (c) or a string of characters
(str) into the serial port a instance's transmit queue to be
transmitted. If the transmit queue becomes full, Cport::Put
will not attempt to put any more characters in the queue.
Return value Cport::Put returns the actual number of characters put
into the transmit queue. For single characters, this value
will be either 0 or 1.
See also Cport::Out, Cport::Get, Cport::LenTx
Example Echo the keyboard to the serial port when fetching a
keystroke.
#include <conio.h>
static Cport echo(COM2, B9600, W8|S1|NONE ,1024 , 64);
char GetKey(void)
{
char c;
if(kbhit())
{
c = getch();
echo.Put(c);
return(c);
}
else
return('\0');
}
5-21
Example Dial a number on the modem.
#include <string.h>
void ModDial(Cport& modem, const char* number)
{
char dial[24] = "ATDT";
strcat(dial, number);
strcat(dial, "\r");
modem.Put(dial);
}
Cport::Out
------------------------------------------------------------------
Function Puts a block of bytes into a serial port's transmit queue.
Syntax #include "cport.h"
unsigned Cport::Out(const void *abyte, unsigned nbyte);
Parameters
abyte - Pointer to the block to be put into the transmit queue.
nbyte - Number of bytes to be put into the transmit queue.
Remarks Cport::Out puts the block of bytes pointed to by abyte into
the serial port instance's transmit queue to be transmitted.
Return value Cport::Out returns the number of bytes actually put into
the transmit queue.
See also Cport::In, Cport::Put, Cport::LenTx
Example Send a block of 128 bytes to the transmitter.
#define BLK_SZ 128
int SendBlock(Cport& com, byte* block)
{
int rv;
rv = com.Out(block, BLK_SZ);
if(rv < BLK_SZ)
return(-1);
else
return(0);
}
5-22
Cport::FlushTx
------------------------------------------------------------------
Function Flushes a serial port's transmit queue.
Syntax #include "cport.h"
void Cport::FlushTx();
Remarks Cport::FlushTx deletes any existing characters in the serial
port instance's transmit queue.
See also Cport::FlushRx, Cport::LenTx
Example If a transmit flush command is in order, flush the transmit
queue.
void RemoteCommand(Cport& com, int command)
{
switch(command)
{
case TX_FLUSH:
com.FlushTx();
break;
case RX_FLUSH:
com.FlushRx();
break;
...continued
}
}
Cport::LenTx
------------------------------------------------------------------
Function Calculates the number of characters/bytes in a serial
port's transmit queue.
Syntax #include "cport.h"
unsigned Cport::LenTx();
Remarks Cport::LenTx calculates the number of characters/bytes
in the serial port instance's transmit queue.
Return value Cport::LenTx returns the number of characters/bytes
in the transmit queue.
See also Cport::LenRx, Cport::FlushTx
Example Check if the transmitter has reached 3/4 of capacity.
#define TX_SIZE 1024
int IsAboveThresh(Cport& sprinter)
{
return(sprinter.LenTx() > (TX_SIZE * 3 / 4));
}
5-23
Cport::TxWait
------------------------------------------------------------------
Function Waits for a serial port's transmitter to empty
Syntax #include "cport.h"
void Cport::TxWait();
Remarks When a transmit queue becomes empty, the UART may not have
actually transmitted the last of the bytes. A program may need
to know when all the data has actually been transmitted so
that it may, for example, change the state of the hardware
lines. Cport::TxWait will return after the UART has been
emptied of data.
See Also Cport::LenTx
Example Send a string to a half duplex device. This examples assumes
that the device is monitoring our RTS line to determine a
transmit or receive state.
void SendMessage(Cport device, const char* msg)
{
device.Rts(ON);
device.Put(msg);
while(device.LenTx());
device.TxWait();
device.Rts(OFF);
}
5-24
Status Functions
----------------
Basic
Cport::Error detects hardware and software errors.
Intermediate
Cport::Status returns the status of the software and input hardware lines.
Cport::Rts controls the RTS output line.
Cport::Dtr controls the DTR output line.
Advanced
Cport::Out1 controls the general purpose OUT1 output line.
Cport::Uart determines what type of UART chip is residing at a serial port.
5-25
Cport::Error
------------------------------------------------------------------
Function Determines if any errors have occurred on a serial port since
the last call to Cport::Error.
Syntax #include "cport.h"
unsigned Cport::Error();
Remarks Cport::Error determines if any errors are pending on the
serial port instance. After a call to Cport::Error, the errors
are cleared. Cport::Error returns a bit ORed error word. See
Table A-7 on Appendix A for a list of bit definitions.
Return value If an error has occurred, Cport::Error returns an error
word. If no errors have occurred, it returns a 0.
See also Cport::Status
Example Determine the source of the error if one has occurred.
#define HARDWARE (PARITY | FRAMING | BREAK | RX_FIFO)
void CheckForErrors(Cport& dvm)
{
unsigned err;
if((err = dvm.Error()) == 0)
return;
else if(err & OVERUN)
{
// over run error
}
else if(err & HARDWARE)
{
// hardware errors
}
else if(err & (TXFULL | RXFULL))
{
// queue errors
}
}
Cport::Status
------------------------------------------------------------------
Function Retrieves the status of a serial port's software and hardware
lines.
Syntax #include "cport.h"
unsigned Cport::Status();
5-26
Remarks Cport::Status retrieves the status of the serial port
instance's software and hardware lines. Cport::Status returns
a bit ORed status word. See Table A-8 in Appendix A for a list
of bit definitions.
Return value Cport::Status returns the status word of the software and
hardware lines.
See also Cport::Error, Cport::Rts, Cport::Dtr
Example Test if the modem is powered up and ready.
#include <dos.h>
int CheckModem(Cport& modem)
{
modem.Dtr(ON);
delay(40);
return((modem.Status() & DSR) != 0);
}
Cport::Rts
------------------------------------------------------------------
Function Sets or clears a serial port's Request to Send line.
Syntax #include "cport.h"
void Cport::Rts(byte on_off);
Parameters
on_off - Determines whether RTS is to be set or cleared. See Table A-10
in Appendix A.
Remarks Cport::Rts sets or clears the serial port instance's RTS line,
depending on the value of on_off. If the value of on_off is
ON, RTS is asserted. If the value of on_off is OFF, RTS is
inhibited. In many cases, this signal will be looked at by the
remote device to determine if it is safe to transmit. This
gives the programmer the ability to turn off the remote
device's transmitter.
NOTE: Cport::Rts should never be called when RTS hardware
handshaking is enabled.
See also Cport::Dtr, Cport::Status, Cport::Handshake
5-27
Example Put the device in an on or off line state. (Assumes the remote
device will not send data without our RTS asserted)
void OffLine(Cport& device)
{
device.Rts(OFF);
}
void OnLine(Cport& device)
{
device.Rts(ON);
}
Cport::Dtr
------------------------------------------------------------------
Function Sets or clears a serial port's Data Terminal Ready line.
Syntax #include "cport.h"
void Cport::Dtr(byte on_off);
Parameters
on_off - Determines whether DTR is to be asserted or inhibited. See
Table A-10 in Appendix A.
Remarks Cport::Dtr set or clears the serial port instance's DTR line,
depending on the value of on_off. If the value of on_off is
ON, DTR is asserted. If the value of on_off is OFF, DTR is
inhibited. In many cases, this signal will be looked at by the
remote device to determine if it is safe to transmit. This
gives the programmer the ability to turn off the remote
device's transmitter.
NOTE: Cport::Dtr should never be called when DTR hardware
handshaking is enabled.
See also Cport::Rts, Cport::Status, Cport::Handshake
Example Put the device in an on or off line state. (Assumes the remote
device will not send data without our DTR asserted).
void OffLine(Cport& device)
{
device.Dtr(OFF);
}
void OnLine(Cport& device)
{
device.Dtr(ON);
}
5-28
Cport::Out1
------------------------------------------------------------------
Function Sets or clears a serial port's Out1 line.
Syntax #include "cport.h"
void Cport::Out1(byte on_off);
Parameters
on_off - Determines whether OUT1 is to be asserted or inhibited. See
Table A-10 in Appendix A.
Remarks Cport::Out1 sets or clears the serial port instance's general
purpose OUT1 line depending on the value of on_off. If the
value of on_off is ON, OUT1 is asserted. If the value of
on_off is OFF, OUT1 is inhibited. OUT1 is a general purpose
output sometimes utilized by a device for a special feature or
reset.
See also Cport::Rts, Cport::Dtr
Example Reset a smart modem.
void SmartReset(Cport& modem)
{
modem.Out1(ON);
delay(50);
modem.Out1(OFF);
}
Cport::Uart
------------------------------------------------------------------
Function Determines the type of UART at a serial port.
Syntax #include "cport.h"
int Cport::Uart();
Remarks Cport::Uart determines the type of UART chip that resides
at the instance's serial port. See Table A-11 for a list of
UART types.
Return value Cport::Uart returns a value representative of the type of
UART that was detected.
See Also Cport::NS550
Example If the serial port instance has an NS16550 UART, set the
trigger level to 1 byte.
void SetThreshIf550(Cport& com)
{
if(com.Uart() == NS16550)
com.NS550(T550_1);
}
5-29
Data Integrity
--------------
Intermediate
Cport::Checksum calculates a byte checksum of a block of data.
Cport::Crc16 calculates a 16 bit cyclic redundancy check (CRC) on a
block of data.
Cport::Crc32.calculates a 32 bit cyclic redundancy check (CRC) on a
block of data.
5-30
Cport::Checksum
------------------------------------------------------------------
Function Performs a byte checksum calculation on a block of data.
Syntax #include "cport.h"
static byte Cport::Checksum(const void *abyte, unsigned nbyte);
Parameters
abyte - Pointer to the block on which the checksum is to be performed.
nbyte - Number of bytes in the block.
Remarks Cport::Checksum performs a byte checksum on the block of bytes
pointed to by abyte. The checksum is calculated by summing all
the bytes in the block.
Return value Cport::Checksum returns a one byte checksum.
See also Cport::Crc16, Cport::Crc32, Cport::In, Cport::Out
Example Verify that the actual checksum matches the received checksum.
struct Xblock
{
byte num;
byte _num;
byte data[128];
byte checksum;
}block;
int GetXblock(Cport& com, Xblock& block)
{
com.In(&block, sizeof(Xblock));
if((com.Checksum(block.data, 128) - block.checksum) != 0)
return(-1);
else
return(0);
}
Cport::Crc16
------------------------------------------------------------------
Function Performs a 16 bit cyclic redundancy check on a block of data.
Syntax #include "cport.h"
static unsigned ComCrc16(const void *abyte, unsigned nbyte);
Parameters
abyte - Pointer to the block on which the 16 bit cyclic redundancy
check is to be performed.
5-31
nbyte - Number of bytes in the block.
Remarks Cport::Crc16 performs a 16 bit cyclic redundancy check on the
block of data pointed to by abyte.
Return value Cport::Crc16 returns the 16 bit CRC value.
See also Cport::Crc32, Cport::Checksum, Cport::In, Cport::Out
Example Verify that the actual CRC matches the received CRC.
struct Xblock{
byte num;
byte _num;
byte data[128];
unsigned crc;
}block;
int GetXblock(Cport& com, Xblock& block)
{
com.In(&block, sizeof(Xblock));
// Check the calculated CRC against the block CRC.
//
if(com.Crc16(block.data, 128) != block.crc)
return(-1);
else
return(0);
}
Cport::Crc32
------------------------------------------------------------------
Function Performs a 32 bit cyclic redundancy check on a block of data.
Syntax #include "cport.h"
static unsigned long ComCrc32(const void *abyte, unsigned nbyte);
Parameters
abyte - Pointer to the block on which the 32 bit cyclic redundancy
check is to be performed.
nbyte - Number of bytes in the block.
Remarks Cport::Crc32 performs a 32 bit cyclic redundancy check on the
block of data pointed to by abyte.
Return value Cport::Crc32 returns the 32 bit CRC value.
See also Cport::Crc16, Cport::Checksum, Cport::In, Cport::Out
5-32
Example Verify that the actual CRC matches the received CRC.
struct Packet {
byte num;
byte data[1024];
unsigned long crc;
}packet;
int GetPacket(Cport& com, Packet& packet)
{
com.In(&packet, sizeof(Packet));
// Check the calculated CRC against the packet's CRC.
//
if(com.Crc32(packet.data, 1024) != packet.crc)
return(-1);
else
return(0);
}
5-33
Misc Functions
--------------
Advanced
Cport::SetBreak sets a break condition.
Cport::ClrBreak clears a break condition.
Cport::Scratch writes to or reads from the UART's scratch register.
5-34
Cport::SetBreak
------------------------------------------------------------------
Function Set a break condition on a serial port.
Syntax #include "cport.h"
void Cport::SetBreak();
Remarks Cport::SetBreak sets a break condition on the serial port
instance. The break condition will stay in effect until a
subsequent call to Cport::ClrBreak is made.
See also Cport::ClrBreak
Example If the an abort condition has been declared, set a break
condition. When it clears, release the break condition.
void Abort(Cport& com, int abrt)
{
static int brkflg;
if(abrt && !brkflg)
com.SetBreak();
else if(!abrt && brkflg)
com.ClrBreak();
}
Cport::ClrBreak
------------------------------------------------------------------
Function Clears a previously set break condition on a serial port.
Syntax #include "cport.h"
void Cport::ClrBreak();
Remarks Cport::ClrBreak clears a previously set break condition on the
serial port instance.
See also Cport::SetBreak
Example If the an abort condition has been declared, set a break
condition. When it clears, release the break condition.
void Abort(Cport& com, int abrt)
{
static int brkflg;
if(abrt && !brkflg)
com.SetBreak();
else if(!abrt && brkflg)
com.ClrBreak();
}
5-35
Cport::Scratch
------------------------------------------------------------------
Function Writes a byte to, or reads a byte from the serial port's
scratch register.
Syntax #include "cport.h"
void Cport::Scratch(byte abyte);
or
byte Cport::Scratch();
Parameters
abyte - The byte to be written to the scratch register.
Remarks If a parameter is specified, Cport::Scratch writes the byte
value abyte to the serial port instance's UART scratch
register. If Cport::Scratch is called with no parameters, it
reads the byte in the UART scratch register. Not all UARTs
have a scratch register.
Example Exchange a value with the scratch register.
byte ScratchExchange(Cport& com, byte value)
{
byte rv;
rv = com.Scratch(); // read the scratch register
com.Scratch(value); // write to the scratch register
return(rv);
}
6-1
File Transfer
=============
Xmodem
------
XmodemTx transmits a file using the Xmodem file transfer protocol.
XmodemRx receives a file using the Xmodem file transfer protocol.
Xcallback is the default callback function for XmodemTx and XmodemRx.
6-2
XmodemTx
------------------------------------------------------------------
Function Transmits a file with the Xmodem file transfer protocol.
Syntax #include "xmodem.h"
int XmodemTx(COM, const char* file,
int (*cb)(int msg, XPARAM param));
or
int XmodemTx(Cport&, const char* file,
int (*cb)(int msg, XPARAM param));
Parameters
COM - Handle of the serial port (C).
Cport - Reference to a serial port instance (C++).
file - Path/name of the file to be transferred.
cb - Pointer to the callback function.
Remarks XmodemTx transmits the file file via the serial port specified
by COM or Cport. It will make calls back to the function cb if
one is specified. If you specify NULL for cb, a default
callback function will be used. See the following discussion
on the callback function for a complete explanation of the
callback function.
Return value XmodemTx returns zero if the file was transferred
successfully. Otherwise, it returns non-zero. See Table
6-1 for a list of return codes.
See also XmodemRx, Xcallback
Example Transfer the file cport.zip via the modem. (C)
/* callback function prototype */
int myCallback(int msg, XPARAM param);
int main(void)
{
COM modem;
int rv;
modem = ComOpen(COM1, B2400, W8|S1|NONE, 1024, 512);
if(comopen_errno != NO_ERR)
return(-comopen_errno);
rv = XmodemTx(modem, "cport.zip", myCallback);
ComClose(modem);
return(rv);
}
6-3
Example Transfer the file cport.zip via the modem. (C++)
// callback function prototype
int myCallback(int msg, XPARAM param);
int main(void)
{
Cport modem(COM1, B2400); // uses default parameters
if((int)modem != NO_ERR)
return(-((int)modem));
return(XmodemTx(modem, "cport.zip", myCallback));
}
XmodemRx
------------------------------------------------------------------
Function Receives a file with the Xmodem file transfer protocol.
Syntax #include "xmodem.h"
int XmodemRx(COM, const char* file,
int (*cb)(int msg, XPARAM param));
or
int XmodemRx(Cport&, const char* file,
int (*cb)(int msg, XPARAM param));
Parameters
COM - Handle of the serial port (C).
Cport - Reference to a serial port instance (C++).
file - Path/name of the file to be transferred.
cb - Pointer to the callback function.
Remarks XmodemRx receives the file file via the serial port specified
by COM or Cport. It will make calls back to the function cb
if one is specified. If you specify NULL for cb, a default
callback function will be used. See the following discussion
on the callback function for a complete explanation of the
callback function.
Return value XmodemTx returns zero if the file was transferred
successfully. Otherwise, it returns non-zero. See Table
6-1 for a list of return codes.
See also XmodemTx, Xcallback
6-4
Example Receive the file cport.zip via the modem. (C)
/* callback function prototype */
int myCallback(int msg, XPARAM param);
int main(void)
{
COM modem;
int rv;
modem = ComOpen(COM1, B2400, W8|S1|NONE, 1024, 512);
if(comopen_errno != NO_ERR)
return(-comopen_errno);
rv = XmodemRx(modem, "cport.zip", myCallback);
ComClose(modem);
return(rv);
}
Example Receive the file cport.zip via the modem. (C++)
// callback function prototype
int myCallback(int msg, XPARAM param);
int main(void)
{
Cport modem(COM1, B2400); // uses default parameters
if((int)modem != NO_ERR)
return(-((int)modem));
return(XmodemRx(modem, "cport.zip", myCallback));
}
Xcallback
------------------------------------------------------------------
Function Default callback function.
Syntax #include "xmodem.h"
int Xcallback(int msg, XPARAM param);
Parameters
msg - Callback message number. (See Table 6-2).
param - Message specific parameter. (See Table 6-2 and 6-3)
Remarks Xcallback is the default Xmodem callback function. When NULL
is specified as the callback function in a call to XmodemTx
or XmodemRx, Xcallback will be used. Xcallback only keeps
track of errors to decide if the transfer should be aborted.
You can chain callback functions by specifying a callback
function and then calling Xcallback directly. You would do
this if you were only interested in the information provided
6-5
to the callback function and did not want to affect the
functionality of the transfer.
Return value When a callback function returns zero, the transfer
continues. If it returns non-zero, the transfer is
canceled, and XmodemRx or XmodemTx will return with a
non-zero return code.
See also XmodemTx, XmodemRx
Example Use the default callback when receiving the file cport.zip
via the modem. This results in a blind transfer.
int main(void)
{
COM modem;
int rv;
modem = ComOpen(COM1, B2400, W8|S1|NONE, 1024, 512);
if(comopen_errno != NO_ERR)
return(-comopen_errno);
rv = XmodemRx(modem, "cport.zip", NULL);
ComClose(modem);
return(rv);
}
Example Establish a callback function for procuring information for
screen updates only.
int myCallback(int msg, XPARAM param)
{
switch(msg)
{
case XM_BLOCKCHECK:
/* Update the screen */
break;
case XM_BLOCK:
/* Update the screen */
break;
case...
}
/* chain to the default callback for functionality
*/
return(Xcallback(msg, param));
}
Callback Function
------------------------------------------------------------------
Since it usually takes time to transfer a file, there must be a mechanism
for monitoring and optionally canceling the transfer. To accomplish this,
the Xmodem transmit and receive functions accept a parameter, which is a
pointer to a callback function. This function will be called at certain
6-6
points during the file transfer. Your callback function can be used to
update the screen, cancel the transfer, etc. Your callback function must
have the exact prototype:
int function_name(int msg, XPARAM param);
Msg is the message number that identifies why the callback was made.
The value of param depends on the message. It provides additional
information for a specific message. Anytime param is not used, it is set
to zero. The following is a list of messages and their descriptions.
XM_IDLE (0) - Idle time. This message is sent during idle time to give
the callback the opportunity to do something, such as checking to see
if the user wishes to cancel the transfer.
XM_START (1) - Start of transfer. This message is sent, at most, one time.
It signals that the transfer has been successfully prepared and will
now attempt to make contact with the remote station.
XM_BLOCKCHECK (2) - Block check determined. Once the block check has
been determined, this message is sent to inform the callback if the
block check will be checksum (param == 0) or CRC16 (param != 0). This
message is sent, at most, one time during a transfer. It is mostly
informative .
XM_BLOCK (3) - New block transferred. This message is sent each time a new
block (128 bytes) is successfully transferred. For this message, param
contains the block number. This message is primarily an informative
message.
XM_EOT (4) - End of transmission. This message is sent when an end of
transmission is being established. Usually there will be only one of
these messages, however, if problems arise, the EOT may be retried.
XM_DONE (5) - Transfer done. This message is sent at the end of a
transmission whether the transmission was successful or canceled. It
is sent exactly one time if XM_START was previously sent. Otherwise,
it will not be sent.
XM_ERROR (6) - Error detected. This message is sent when an error is
detected in the data. Param contains the error code. The lower 12 bits
of param is the bit ORed errors returned by the function ComError.
The upper 4 bits is the extended Xmodem error code (not bit ORed).
The extended Xmodem error code (upper 4 bits) should always be
non-zero. The ComError bits (lower 12 bits) may or may not indicate
errors. Usually the ComError portion of the error code takes precedence
over the extended Xmodem code, since it is likely to be the source of
the error. The extended Xmodem errors are explained here. See ComError
or Cport::Error for information on the lower 12 bits of the error code:
XE_BADBLOCK (0x1000) - Bad block. This error occurs when a block was
determined to be corrupted. Occasional bad block errors may occur. If
the transfer is not canceled by the callback function, Xmodem will
attempt to recover from this error (usually succeeding) by retrying
the block.
6-7
XE_BADCHECK (0x2000) - Bad block check. This error occurs when the block
is not detected as bad (XE_BADBLOCK) but the block check (CRC or
checksum) does not match the data. This error can only be detected
when receiving a file.
XE_TIMEOUT (0x3000) - Timeout. Xmodem timed out waiting for a block or
for protocol exchange. If the callback function does not cancel the
transfer, Xmodem will retry whatever timed out. Successful recovery
from this error depends on the reason (usually unknown) for the timeout.
XE_CANCEL (0x4000) - Transmission canceled. This message is sent when
the transmission is canceled by either the callback function, by the
remote station or for other internal reasons.
Xmodem Tables of Values
------------------------------------------------------------------
name value description
-----------------------------------------------
XR_NOERR (0) No error.
XR_FILEERR (1) File error.
XR_CANCEL (2) Transfer canceled.
XR_ALLOC (3) Memory allocation error.
Table 6-1 - XmodemRx/XmodemTx return values.
name value description XPARAM
-------------------------------------------------------------------------
XM_IDLE (0) Idle time. 0.
XM_START (1) Start of transfer 0.
XM_BLOCKCHECK (2) Block check determined 0 if checksum, 1 if CRC16.
XM_BLOCK (3) New block transferred Block number.
XM_EOT (4) End of transmission 0.
XM_DONE (5) Transfer complete 0.
XM_ERROR (6) Error has been detected Error code.
Table 6-2 - Xmodem callback messages.
name value description
------------------------------------------------------------
XE_BADBLOCK (0x1000) Bad block.
XE_BADCHECK (0x2000) Bad block check (CRC or checksum).
XE_TIMEOUT (0x3000) Timeout.
XE_CANCEL (0x4000) Transfer canceled.
Table 6-3 - Extended Xmodem error codes.
A-1
Appendix A
==========
name value
-----------------------
* COM1 (PORT0 | IRQ4)
* COM2 (PORT1 | IRQ3)
* COM3 (PORT2 | IRQ4)
* COM4 (PORT3 | IRQ3)
PORT0 (0x03F8)
PORT1 (0x02F8)
PORT2 (0x03E8)
PORT3 (0x02E8)
IRQ2 (0x2000)
IRQ3 (0x3000)
IRQ4 (0x4000)
IRQ5 (0x5000)
IRQ6 (0x6000)
IRQ7 (0x7000)
BIOS0 (*(int far *)0x400000l)
BIOS1 (*(int far *)0x400002l)
BIOS2 (*(int far *)0x400004l)
BIOS3 (*(int far *)0x400006l)
* The COMx constants are usually sufficient.
Table A-1 - Serial port id.
name value
---------------
B115200 (1)
B57600 (2)
B38400 (3)
B19200 (6)
B9600 (12)
B7200 (16)
B4800 (24)
B3600 (32)
B2400 (48)
B2000 (58)
B1800 (64)
B1200 (96)
B600 (192)
B300 (384)
B150 (768)
B110 (1047)
B75 (1536)
B50 (2304)
Table A-2 - Baud rate divisors.
A-2
name value description
----------------------------------------
W8 (0x03) 8 bit words.
W7 (0x02) 7 bit words.
W6 (0x01) 6 bit words.
W5 (0x00) 5 bit words.
S1 (0x00) 1 stop bit.
S2 (0x04) 2 stop bits.
NONE (0x00) No parity.
ODD (0x08) Odd parity.
EVEN (0x18) Even parity.
MARK (0x28) Mark parity (logic 1).
SPACE (0x38) Space parity (logic 0).
WMASK (0x03) Word mask.
SMASK (0x04) Stop bit mask.
PMASK (0x38) Parity mask.
Table A-3 - Bit ORed mode components.
name value description
---------------------------------------------------------------
NO_ERR (0) No errors.
OPENED (1) Serial port is already opened.
BAD_ID (2) Invalid id parameter.
NO_UART (3) No UART chip was detected.
RX_ALC (4) Receive queue allocation error.
TX_ALC (5) Transmit queue allocation error.
MAX_PORT (6) The maximum number of serial ports are opened.
IRQ_CTN (7) The irq contends with another open serial port.
GEN_ALC (8) General memory allocation error.
Table A-4 - Open error values.
name value description
---------------------------------------------------
OFF (0x00) No handshaking.
DTR (0x01) The receiver uses DTR.
RTS (0x02) The receiver uses RTS.
S_RX (0x04) The receiver uses XON/XOFF.
CTS (0x10) CTS is checked by the transmitter.
DSR (0x20) DSR is checked by the transmitter.
DCD (0x80) DCD is checked by the transmitter.
S_TX (0x08) The transmitter honors XON/XOFF.
SOFT (0x0C) Same as (S_RX | S_TX).
HARD1 (0x21) Same as (DTR | DSR).
HARD2 (0x12) Same as (RTS | CTS).
Table A-5 - Bit ORed handshaking options.
A-3
name value description
-----------------------------------
TIMER (0x01) divert timer (irq0).
KEYBOARD (0x02) disable keyboard (irq1).
CASCADE (0x04) disable irq2.
OFF (0x00) restore all interrupts.
Table A-6 - Turbo options.
name value description
-----------------------------------------
OVERUN (0x0002) Overrun error.
PARITY (0x0004) Parity error.
FRAMING (0x0008) Framing error.
BREAK (0x0010) Break detect.
RX_FIFO (0x0080) Rx fifo error.
TXFULL (0x0100) Transmit queue overflow.
RXFULL (0x0200) Receive queue overflow.
(unused) (0xF000) Designated as unused.
Table A-7 - Bit ORed error code.
name value description
-----------------------------------------------
DCTS (0x001) Change in clear to send.
DDSR (0x002) Change in data set ready.
TERI (0x004) Trailing edge ring indicator.
DDCD (0x008) Change in data carrier detect.
CTS (0x010) Clear to send asserted.
DSR (0x020) Data set ready asserted.
RI (0x040) Ring indicator asserted.
DCD (0x080) Data carrier detect asserted.
S_TX_OFF (0x100) Transmitter off (XOFF state).
U_TX_OFF (0x200) Transmitter off (ComTx).
S_RX_OFF (0x400) Receiver off (XOFF state).
Table A-8 - Bit ORed status word.
name value description
----------------------------------------------
ON (1) Turns the transmitter on.
OFF (0) Turns the transmitter off.
TX_DIRECT (0x2) Use direct mode when off.
Table A-9 - Transmitter options.
A-4
name value description
-------------------------------------
ON (1) Signal asserted.
OFF (0) Signal inhibited.
Table A-10 - On/off values.
name value description
--------------------------------------
INS8250 (1) INS8250 or INS8250-B.
NS16450 (2) NS16450 or INS8250A.
NS16550 (3) NS16550.
I82510 (4) 82510 (Intel).
Table A-11 - UART types.
name value description
--------------------------------
T550_1 (0x00) 1 byte.
T550_4 (0x400 4 bytes.
T550_8 (0x80) 8 bytes.
T550_14 (0xC0) 14 bytes.
Table A-12- NS550 trigger thresholds.
B-1
Appendix B
==========
Compiling
---------
1) Make sure the header file(s) are included in any modules (source
files) which make calls to Cport library functions.
Example: #include "cport.h"
2) Make sure your compiler knows where to find the header file(s).
Borland C/C++: bcc -c -Ic:\cport\include your_file
Microsoft C/C++: cl /c /Ic:\cport\include your_file
NOTE: cl will also look at the INCLUDE environment variable for
the include directories.
Example: set INCLUDE=c:\c600\include;c:\cport\include;
3) Make sure your compiler is generating byte alignments when generating
structures. This is only a concern when using Cport functions, which
involve structures such as CPARAM. For Borland and Microsoft
compilers, this is taken care of. If you are using another compiler,
consult your user's manual on how to generate byte alignments.
Borland C/C++: (uses byte alignment by default)
Microsoft C/C++: cl /c /Zp1 /Ic:\cport\include your_file
Linking
-------
1) Make sure the appropriate Cport library is included in the list of
libraries. The last letter in the file name of the libraries
indicates the memory model:
cports.lib - small model
cportm.lib - medium model
cportc.lib - compact model
cportl.lib - large model
cporth.lib - huge model
2) Make sure the linker knows where to find the library files.
Borland C/C++: tlink /Lc:\cport\lib c0s objs, exe_name, map_name, cports cs
Microsoft C/C++: link objs, exe_name, map_name, cports slibce;
NOTE: link looks at the LIB environment variable for the library
directories:
Example: set LIB=c:\c600\lib;c:\cport\lib;
C-1
Appendix C
==========
Cport v2.0 Order Form
Name: ___________________________________________________________
Company: ________________________________________________________
Address: ________________________________________________________
City: _________________________________ State: _________________
Zip Code: _________________ Phone # : __________________________
CompuServe # : __________________________________________________
How did you acquire Cport ? _____________________________________
Compiler(s): ____________________________________________________
Computer(s): ____________________________________________________
Operating system(s): ____________________________________________
Single Licence .... $65.00
2 Licenses ........ $59.00 each
3 to 4 Licenses ... $54.00 each
5 to 9 licenses ... $48.00 each
10+ licenses ...... $41.00 each
Quantity price each
Subtotal _________ X __________ = $________
California residents add sales tax ( 8.25% ) $________
Shipping outside continental U.S. add ( $ 5.00) $________
Total: $________
All Payments Must be in U.S. Dollars
Make check or money order payable to: Bri Productions
39120 Argonaut Way, Ste 772
Fremont, CA 94538-1378
Visa/Master Card#:___________________ Expiration Date:_________
Signature (Credit card only):___________________________________
C-2
We want to hear from you!
-------------------------
In order to improve Cport and add valuable features, we need to know what
features you need most. This information is important in order to provide
you with the best possible product. Please take a moment to answer the
following questions.
Indicate your need for the following features by checking the choice
which best describes your need for the feature:
very | nice | don't
important | to have | need it
----------- -------- ---------
Multi port Serial Boards: ____ ____ ____
Board name(s) ______________
Modem support: ____ ____ ____
Zmodem file transfer: ____ ____ ____
Other file transfer __________: ____ ____ ____
Other file transfer __________: ____ ____ ____
Windows support: ____ ____ ____
Other ________________________: ____ ____ ____
Other ________________________: ____ ____ ____
Other ________________________: ____ ____ ____
What other types of libraries would you find useful ? _____
___Game Port ___Expanded Memory ___Sound effects
Others______________________________________________________
Other Comments______________________________________________
____________________________________________________________
____________________________________________________________
Bri Productions, 39120 Argonaut Way, Ste 772, Fremont, CA 94538-1378
(510) 794-0616